Passed
Pull Request — master (#5831)
by
unknown
08:20
created

SessionManager::formatSessionsAdminForGrid()   F

Complexity

Conditions 26
Paths 3846

Size

Total Lines 117
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 63
nc 3846
nop 5
dl 0
loc 117
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Asset;
6
use Chamilo\CoreBundle\Entity\Course;
7
use Chamilo\CoreBundle\Entity\ExtraField;
8
use Chamilo\CoreBundle\Entity\SequenceResource;
9
use Chamilo\CoreBundle\Entity\Session;
10
use Chamilo\CoreBundle\Entity\SessionCategory;
11
use Chamilo\CoreBundle\Entity\SessionRelCourse;
12
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
13
use Chamilo\CoreBundle\Entity\SessionRelUser;
14
use Chamilo\CoreBundle\Entity\User;
15
use Chamilo\CoreBundle\Framework\Container;
16
use Chamilo\CourseBundle\Entity\CSurvey;
17
use ExtraField as ExtraFieldModel;
18
use Monolog\Logger;
19
use Symfony\Component\HttpFoundation\File\UploadedFile;
20
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
21
use Chamilo\CoreBundle\Component\Utils\ObjectIcon;
22
use Chamilo\CoreBundle\Component\Utils\StateIcon;
23
24
/**
25
 * This is the session library for Chamilo
26
 * (as in courses>session, not as in PHP session)
27
 * All main sessions functions should be placed here.
28
 * This class provides methods for sessions management.
29
 * Include/require it in your code to use its features.
30
 */
31
class SessionManager
32
{
33
    public const STATUS_PLANNED = 1;
34
    public const STATUS_PROGRESS = 2;
35
    public const STATUS_FINISHED = 3;
36
    public const STATUS_CANCELLED = 4;
37
    // See BT#4871
38
    public const SESSION_CHANGE_USER_REASON_SCHEDULE = 1;
39
    public const SESSION_CHANGE_USER_REASON_CLASSROOM = 2;
40
    public const SESSION_CHANGE_USER_REASON_LOCATION = 3;
41
    public const SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION = 4;
42
    public const DEFAULT_VISIBILITY = 4;  //SESSION_AVAILABLE
43
44
    public function __construct()
45
    {
46
    }
47
48
    /**
49
     * Fetches a session from the database.
50
     *
51
     * @param int $id Session Id
52
     *
53
     * @return array Session details
54
     */
55
    public static function fetch($id)
56
    {
57
        if (empty($id)) {
58
            return [];
59
        }
60
61
        $session = api_get_session_entity($id);
62
63
        if (!$session) {
64
            return [];
65
        }
66
67
        $result = [
68
            'id' => $session->getId(),
69
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
70
            'name' => $session->getTitle(), // only provided for backwards compatibility - should be removed in the long run
71
            'title' => $session->getTitle(),
72
            'description' => $session->getDescription(),
73
            'show_description' => $session->getShowDescription(),
74
            'duration' => $session->getDuration(),
75
            'nbr_courses' => $session->getNbrCourses(),
76
            'nbr_users' => $session->getNbrUsers(),
77
            'nbr_classes' => $session->getNbrClasses(),
78
            'visibility' => $session->getVisibility(),
79
            'promotion_id' => $session->getPromotion() ? $session->getPromotion()->getId() : 0,
80
            'display_start_date' => $session->getDisplayStartDate()?->format('Y-m-d H:i:s'),
81
            'display_end_date' => $session->getDisplayEndDate()?->format('Y-m-d H:i:s'),
82
            'access_start_date' => $session->getAccessStartDate()?->format('Y-m-d H:i:s'),
83
            'access_end_date' => $session->getAccessEndDate()?->format('Y-m-d H:i:s'),
84
            'coach_access_start_date' => $session->getCoachAccessStartDate()?->format('Y-m-d H:i:s'),
85
            'coach_access_end_date' => $session->getCoachAccessEndDate()?->format('Y-m-d H:i:s'),
86
            'send_subscription_notification' => $session->getSendSubscriptionNotification(),
87
            'status' => $session->getStatus(),
88
            'status_label' => self::getStatusLabel($session->getStatus()),
89
        ];
90
91
        // Converted to local values
92
        $variables = [
93
            'display_start_date',
94
            'display_end_date',
95
            'access_start_date',
96
            'access_end_date',
97
            'coach_access_start_date',
98
            'coach_access_end_date',
99
        ];
100
101
        foreach ($variables as $value) {
102
            $result[$value.'_to_local_time'] = null;
103
            if (!empty($result[$value])) {
104
                $result[$value.'_to_local_time'] = api_get_local_time($result[$value]);
105
            }
106
        }
107
108
        return $result;
109
    }
110
111
    /**
112
     * Create a session.
113
     *
114
     * @author Carlos Vargas <[email protected]>, from existing code
115
     *
116
     * @param string $name
117
     * @param string $startDate                    (YYYY-MM-DD hh:mm:ss)
118
     * @param string $endDate                      (YYYY-MM-DD hh:mm:ss)
119
     * @param string $displayStartDate             (YYYY-MM-DD hh:mm:ss)
120
     * @param string $displayEndDate               (YYYY-MM-DD hh:mm:ss)
121
     * @param string $coachStartDate               (YYYY-MM-DD hh:mm:ss)
122
     * @param string $coachEndDate                 (YYYY-MM-DD hh:mm:ss)
123
     * @param array  $coachesId                      If int, this is the session coach id,
124
     *                                             if string, the coach ID will be looked for from the user table
125
     * @param int    $sessionCategoryId            ID of the session category in which this session is registered
126
     * @param int    $visibility                   Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
127
     * @param bool   $fixSessionNameIfExists
128
     * @param string $duration
129
     * @param string $description                  Optional. The session description
130
     * @param int    $showDescription              Optional. Whether show the session description
131
     * @param array  $extraFields
132
     * @param int    $sessionAdminId               Optional. If this sessions was created by a session admin, assign it to him
133
     * @param bool   $sendSubscriptionNotification Optional.
134
     *                                             Whether send a mail notification to users being subscribed
135
     * @param int    $accessUrlId                  Optional.
136
     * @param int    $status
137
     *
138
     * @return mixed Session ID on success, error message otherwise
139
     *
140
     * @todo use an array to replace all this parameters or use the model.lib.php ...
141
     */
142
    public static function create_session(
143
        $name,
144
        $startDate,
145
        $endDate,
146
        $displayStartDate,
147
        $displayEndDate,
148
        $coachStartDate,
149
        $coachEndDate,
150
        array $coachesId,
151
        $sessionCategoryId,
152
        $visibility = 1,
153
        $fixSessionNameIfExists = false,
154
        $duration = null,
155
        $description = null,
156
        $showDescription = 0,
157
        $extraFields = [],
158
        $sessionAdminId = 0,
159
        $sendSubscriptionNotification = false,
160
        $accessUrlId = 0,
161
        $status = 0,
162
        $notifyBoss = false,
163
        $parentId = null,
164
        $daysBeforeFinishingForReinscription = null,
165
        $lastRepetition = false,
166
        $daysBeforeFinishingToCreateNewRepetition = null,
167
        $validityInDays = null
168
    ) {
169
        global $_configuration;
170
171
        // Check portal limits
172
        $accessUrlId = api_is_multiple_url_enabled()
173
            ? (empty($accessUrlId) ? api_get_current_access_url_id() : (int) $accessUrlId)
174
            : 1;
175
176
        $hostingLimitSessions = get_hosting_limit($accessUrlId, 'hosting_limit_sessions');
177
178
        if ($hostingLimitSessions !== null && $hostingLimitSessions > 0) {
179
            $num = self::count_sessions();
180
            if ($num >= $hostingLimitSessions) {
181
                api_warn_hosting_contact('hosting_limit_sessions');
182
183
                return get_lang('The number of sessions limit for this portal has been reached');
184
            }
185
        }
186
187
        $name = trim($name);
188
        $sessionCategoryId = (int) $sessionCategoryId;
189
        $visibility = (int) $visibility;
190
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
191
192
        if (empty($name)) {
193
            return get_lang('A title is required for the session');
194
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') &&
195
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
196
        ) {
197
            return get_lang('Invalid start date was given.');
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
            return get_lang('Invalid end date was given.');
202
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
203
            return get_lang('The first date should be before the end date');
204
        } else {
205
            $ready_to_create = false;
206
            if ($fixSessionNameIfExists) {
207
                $name = self::generateNextSessionName($name);
208
                if ($name) {
209
                    $ready_to_create = true;
210
                } else {
211
                    return get_lang('Session title already exists');
212
                }
213
            } else {
214
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE title='".$name."'");
215
                if (Database::num_rows($rs)) {
216
                    return get_lang('Session title already exists');
217
                }
218
                $ready_to_create = true;
219
            }
220
221
            if ($ready_to_create) {
222
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
223
                $session = new Session();
224
                $session
225
                    ->setTitle($name)
226
                    ->addSessionAdmin(api_get_user_entity($sessionAdminId))
227
                    ->setVisibility($visibility)
228
                    ->setDescription($description)
229
                    ->setShowDescription(1 === $showDescription)
230
                    ->setSendSubscriptionNotification((bool) $sendSubscriptionNotification)
231
                    ->setNotifyBoss((bool) $notifyBoss)
232
                    ->setParentId($parentId)
233
                    ->setDaysToReinscription((int) $daysBeforeFinishingForReinscription)
234
                    ->setLastRepetition($lastRepetition)
235
                    ->setDaysToNewRepetition((int) $daysBeforeFinishingToCreateNewRepetition)
236
                    ->setValidityInDays((int) $validityInDays);
237
238
                foreach ($coachesId as $coachId) {
239
                    $session->addGeneralCoach(api_get_user_entity($coachId));
240
                }
241
242
                $startDate = $startDate ? api_get_utc_datetime($startDate, true, true) : null;
243
                $endDate = $endDate ? api_get_utc_datetime($endDate, true, true) : null;
244
                $displayStartDate = $displayStartDate ? api_get_utc_datetime($displayStartDate, true, true) : null;
245
                $displayEndDate = $displayEndDate ? api_get_utc_datetime($displayEndDate, true, true) : null;
246
                $coachStartDate = $coachStartDate ? api_get_utc_datetime($coachStartDate, true, true) : null;
247
                $coachEndDate = $coachEndDate ? api_get_utc_datetime($coachEndDate, true, true) : null;
248
249
                $session->setAccessStartDate($startDate);
250
                $session->setAccessEndDate($endDate);
251
                $session->setDisplayStartDate($displayStartDate);
252
                $session->setDisplayEndDate($displayEndDate);
253
                $session->setCoachAccessStartDate($coachStartDate);
254
                $session->setCoachAccessEndDate($coachEndDate);
255
                $session->setStatus($status);
256
257
258
                $em = Database::getManager();
259
                $em->persist($session);
260
                $em->flush();
261
                $session_id = $session->getId();
262
                $duration = (int) $duration;
263
                if (!empty($duration)) {
264
                    $sql = "UPDATE $tbl_session SET
265
                        access_start_date = NULL,
266
                        access_end_date = NULL,
267
                        display_start_date = NULL,
268
                        display_end_date = NULL,
269
                        coach_access_start_date = NULL,
270
                        coach_access_end_date = NULL,
271
                        duration = $duration
272
                    WHERE id = $session_id";
273
                    Database::query($sql);
274
                } else {
275
                    $sql = "UPDATE $tbl_session
276
                            SET duration = 0
277
                            WHERE id = $session_id";
278
                    Database::query($sql);
279
                }
280
281
                if (!empty($session_id)) {
282
                    $extraFields['item_id'] = $session_id;
283
                    $sessionFieldValue = new ExtraFieldValue('session');
284
                    $sessionFieldValue->saveFieldValues($extraFields);
285
286
                    // add event to system log
287
                    $user_id = api_get_user_id();
288
                    Event::addEvent(
289
                        LOG_SESSION_CREATE,
290
                        LOG_SESSION_ID,
291
                        $session_id,
292
                        api_get_utc_datetime(),
293
                        $user_id
294
                    );
295
                }
296
297
                return $session_id;
298
            }
299
        }
300
    }
301
302
    /**
303
     * @param string $name
304
     *
305
     * @return bool
306
     */
307
    public static function sessionNameExists($name)
308
    {
309
        $name = Database::escape_string($name);
310
        $sql = "SELECT COUNT(*) as count FROM ".Database::get_main_table(TABLE_MAIN_SESSION)."
311
                WHERE title = '$name'";
312
        $result = Database::fetch_array(Database::query($sql));
313
314
        return $result['count'] > 0;
315
    }
316
317
    /**
318
     * @param string $where_condition
319
     *
320
     * @return mixed
321
     */
322
    public static function get_count_admin($where_condition = '')
323
    {
324
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
325
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
326
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
327
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
328
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
329
330
        $where = 'WHERE 1=1 ';
331
        $user_id = api_get_user_id();
332
        $extraJoin = '';
333
334
        if (api_is_session_admin() &&
335
            'false' == api_get_setting('allow_session_admins_to_manage_all_sessions')
336
        ) {
337
            $where .= " AND (
338
                            sru.user_id = '$user_id' AND
339
                            sru.relation_type IN ('".Session::DRH.", ".Session::SESSION_ADMIN."')
340
                            )
341
                      ";
342
343
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
344
                           ON sru.session_id = s.id ";
345
        }
346
347
        $today = api_get_utc_datetime();
348
        $today = api_strtotime($today, 'UTC');
349
        $today = date('Y-m-d', $today);
350
351
        if (!empty($where_condition)) {
352
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
353
354
            $where_condition = str_replace('category_name', 'sc.title', $where_condition);
355
            $where_condition = str_replace(
356
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
357
                [') GROUP BY s.title HAVING session_active = 1 ', " GROUP BY s.title HAVING session_active = 1 "],
358
                $where_condition
359
            );
360
            $where_condition = str_replace(
361
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
362
                [') GROUP BY s.title HAVING session_active = 0 ', " GROUP BY s.title HAVING session_active = '0' "],
363
                $where_condition
364
            );
365
        } else {
366
            $where_condition = " AND 1 = 1";
367
        }
368
369
        $courseCondition = null;
370
        if (strpos($where_condition, 'c.id')) {
371
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
372
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
373
            $courseCondition = " INNER JOIN $table course_rel_session
374
                                 ON (s.id = course_rel_session.session_id)
375
                                 INNER JOIN $tableCourse c
376
                                 ON (course_rel_session.c_id = c.id)
377
                                ";
378
        }
379
380
        $sql = "SELECT COUNT(id) as total_rows FROM (
381
                SELECT DISTINCT
382
                 IF (
383
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
384
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL ) OR
385
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
386
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
387
				, 1, 0) as session_active,
388
                s.id
389
                FROM $tbl_session s
390
                LEFT JOIN $tbl_session_category sc
391
                ON s.session_category_id = sc.id
392
                INNER JOIN $tbl_user u
393
                ON s.id_coach = u.id
394
                $courseCondition
395
                $extraJoin
396
                $where $where_condition ) as session_table";
397
398
        if (api_is_multiple_url_enabled()) {
399
            $access_url_id = api_get_current_access_url_id();
400
            if (-1 != $access_url_id) {
401
                $where .= " AND ar.access_url_id = $access_url_id ";
402
403
                $sql = "SELECT count(id) as total_rows FROM (
404
                SELECT DISTINCT
405
                  IF (
406
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
407
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
408
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
409
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
410
				, 1, 0)
411
				as session_active,
412
				s.id
413
                FROM $tbl_session s
414
                    LEFT JOIN  $tbl_session_category sc
415
                    ON s.session_category_id = sc.id
416
                    INNER JOIN $tbl_user u ON s.id_coach = u.id
417
                    INNER JOIN $table_access_url_rel_session ar
418
                    ON ar.session_id = s.id
419
                    $courseCondition
420
                    $extraJoin
421
                $where $where_condition) as session_table";
422
            }
423
        }
424
425
        $sql .= !str_contains($sql, 'WHERE') ? ' WHERE u.active <> '.USER_SOFT_DELETED : ' AND u.active <> '.USER_SOFT_DELETED;
426
427
        $result_rows = Database::query($sql);
428
        $row = Database::fetch_array($result_rows);
429
        $num = $row['total_rows'];
430
431
        return $num;
432
    }
433
434
    /**
435
     * Get session list for a session admin or platform admin.
436
     *
437
     * @param int   $userId   User Id for the session admin.
438
     * @param array $options  Order and limit keys.
439
     * @param bool  $getCount Whether to get all the results or only the count.
440
     * @param array $columns  Columns from jqGrid.
441
     * @param string $listType
442
     * @param array $extraFieldsToLoad
443
     * @param bool  $formatted
444
     *
445
     * @return array
446
     */
447
    public static function getSessionsForAdmin(
448
        $userId,
449
        $options = [],
450
        $getCount = false,
451
        $columns = [],
452
        $listType = 'all',
453
        $extraFieldsToLoad = [],
454
        $formatted = false,
455
        $language = ''
456
    ) {
457
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
458
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
459
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
460
461
        $where = 'WHERE 1 = 1 ';
462
463
        $userId = (int) $userId;
464
465
        if (!api_is_platform_admin() && !api_is_session_admin() && !api_is_teacher()) {
466
            api_not_allowed(true);
467
        }
468
469
        $extraFieldModel = new ExtraFieldModel('session');
470
        $conditions = $extraFieldModel->parseConditions($options);
471
472
        $sqlInjectJoins = $conditions['inject_joins'];
473
        $where .= $conditions['where'];
474
        $sqlInjectWhere = $conditions['inject_where'];
475
        $injectExtraFields = $conditions['inject_extra_fields'];
476
        $order = empty($conditions['order']) ? ' ORDER BY s.title ASC' : $conditions['order'];
477
        $limit = $conditions['limit'];
478
479
        $isMakingOrder = false;
480
        $showCountUsers = false;
481
482
        if (true === $getCount) {
483
            $select = ' SELECT count(DISTINCT s.id) as total_rows ';
484
        } else {
485
            if (!empty($columns['column_model'])) {
486
                foreach ($columns['column_model'] as $column) {
487
                    if ('users' == $column['name']) {
488
                        $showCountUsers = true;
489
                        break;
490
                    }
491
                }
492
            }
493
494
            $select =
495
                "SELECT DISTINCT
496
                     s.title,
497
                     s.display_start_date,
498
                     s.display_end_date,
499
                     access_start_date,
500
                     access_end_date,
501
                     s.visibility,
502
                     s.session_category_id,
503
                     s.id
504
             ";
505
506
            // ofaj fix
507
            if (!empty($extraFieldsToLoad)) {
508
                $select = "SELECT DISTINCT s.* ";
509
            }
510
            $select .= ', status';
511
512
            if ('replication' === $listType) {
513
                $select .= ', parent_id';
514
            }
515
516
            if (isset($options['order'])) {
517
                $isMakingOrder = 0 === strpos($options['order'], 'category_name');
518
            }
519
        }
520
521
        $isFilteringSessionCategory = false !== strpos($where, 'category_name');
522
        $isFilteringSessionCategoryWithName = false !== strpos($where, 'sc.title');
523
524
        if ($isMakingOrder || $isFilteringSessionCategory || $isFilteringSessionCategoryWithName) {
525
            $sqlInjectJoins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
526
527
            if ($isFilteringSessionCategory) {
528
                $where = str_replace('category_name', 'sc.title', $where);
529
            }
530
531
            if ($isMakingOrder) {
532
                $order = str_replace('category_name', 'sc.title', $order);
533
            }
534
        }
535
536
        if (!empty($language)) {
537
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
538
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
539
            $sqlInjectJoins .= " INNER JOIN $table sc ON (sc.session_id = s.id)
540
                               INNER JOIN $tableCourse c ON (sc.c_id = c.id)";
541
            $language = Database::escape_string($language);
542
543
            // Get the isoCode to filter course_language
544
            $isoCode = '';
545
            $languageId = api_get_language_id($language);
546
            if (!empty($languageId)) {
547
                $languageInfo = api_get_language_info($languageId);
548
                $isoCode = $languageInfo['isocode'];
549
            }
550
            if ('true' === api_get_setting('language.allow_course_multiple_languages')) {
551
                $tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
552
                $tblExtraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
553
                $extraFieldType = ExtraField::COURSE_FIELD_TYPE;
554
                $sql = "SELECT id FROM $tblExtraField WHERE item_type = $extraFieldType AND variable = 'multiple_language'";
555
                $rs = Database::query($sql);
556
                if (Database::num_rows($rs) > 0) {
557
                    $fieldId = Database::result($rs, 0, 0);
558
                    $sqlInjectJoins .= " LEFT JOIN $tblExtraFieldValue cfv ON (c.id = cfv.item_id AND cfv.field_id = $fieldId)";
559
                    $where .= " AND (c.course_language = '$isoCode' OR cfv.field_value LIKE '%$language%')";
560
                } else {
561
                    $where .= " AND c.course_language = '$isoCode' ";
562
                }
563
            } else {
564
                $where .= " AND c.course_language = '$isoCode' ";
565
            }
566
        }
567
568
        $allowSessionAdminsToManageAllSessions = !api_is_platform_admin()
569
            && api_is_session_admin()
570
            && 'false' === api_get_setting('allow_session_admins_to_manage_all_sessions');
571
572
        $allowTeachersToCreateSessions = !api_is_platform_admin()
573
            && api_is_teacher()
574
            && 'true' === api_get_setting('allow_teachers_to_create_sessions');
575
576
        if ($allowSessionAdminsToManageAllSessions || $allowTeachersToCreateSessions) {
577
            $sqlInjectJoins .= " INNER JOIN $tblSessionRelUser sru ON sru.session_id = s.id ";
578
579
            $relationTypeList = [];
580
581
            if ($allowSessionAdminsToManageAllSessions) {
582
                $relationTypeList[] = Session::SESSION_ADMIN;
583
            }
584
585
            if ($allowTeachersToCreateSessions) {
586
                $relationTypeList[] = Session::GENERAL_COACH;
587
            }
588
589
            $where .= " AND (sru.user_id = $userId AND sru.relation_type IN(".implode(',', $relationTypeList)."))";
590
        }
591
592
        $query = "$select";
593
        if (!empty($injectExtraFields)) {
594
            $injectExtraFields = rtrim(trim($injectExtraFields), ',');
595
            $query .= ", $injectExtraFields";
596
        }
597
        $query .= " FROM $tblSession s $sqlInjectJoins $where $sqlInjectWhere";
598
599
        if (api_is_multiple_url_enabled()) {
600
            $tblAccessUrlRelSession = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
601
            $accessUrlId = api_get_current_access_url_id();
602
603
            if (-1 != $accessUrlId) {
604
                $where .= " AND ar.access_url_id = $accessUrlId ";
605
                $query = "$select
606
                    FROM $tblSession s $sqlInjectJoins
607
                    INNER JOIN $tblAccessUrlRelSession ar
608
                    ON (ar.session_id = s.id) $where";
609
            }
610
        }
611
612
        $date = api_get_utc_datetime();
613
614
        switch ($listType) {
615
            case 'all':
616
                break;
617
            case 'active':
618
                $query .= "AND (
619
                    (s.access_end_date IS NULL)
620
                    OR
621
                    (
622
                    s.access_start_date IS NOT NULL AND
623
                    s.access_end_date IS NOT NULL AND
624
                    s.access_start_date <= '$date' AND s.access_end_date >= '$date')
625
                    OR
626
                    (
627
                        s.access_start_date IS NULL AND
628
                        s.access_end_date IS NOT NULL AND
629
                        s.access_end_date >= '$date'
630
                    )
631
                )";
632
                break;
633
            case 'close':
634
                $query .= "AND (
635
                    (
636
                    s.access_start_date IS NOT NULL AND
637
                    s.access_end_date IS NOT NULL AND
638
                    s.access_start_date <= '$date' AND s.access_end_date <= '$date')
639
                    OR
640
                    (
641
                        s.access_start_date IS NULL AND
642
                        s.access_end_date IS NOT NULL AND
643
                        s.access_end_date <= '$date'
644
                    )
645
                )";
646
                break;
647
            case 'replication':
648
                $formatted = false;
649
                $query .= "AND s.days_to_new_repetition IS NOT NULL
650
               AND (SELECT COUNT(id) FROM session AS child WHERE child.parent_id = s.id) <= 1";
651
                break;
652
        }
653
654
        $query .= $order;
655
        $query .= $limit;
656
        if (!$formatted) {
657
            $result = Database::query($query);
658
            $sessions = Database::store_result($result, 'ASSOC');
659
            if ($showCountUsers && !$getCount) {
660
                foreach ($sessions as &$session) {
661
                    $result = Database::query("SELECT COUNT(session_id) AS nbr
662
                    FROM session_rel_user WHERE session_id = {$session['id']} AND relation_type = ".Session::STUDENT);
663
                    $session['users'] = Database::fetch_assoc($result)['nbr'];
664
                }
665
            }
666
667
            if ('replication' === $listType) {
668
                $formattedSessions = [];
669
                foreach ($sessions as $session) {
670
                    $formattedSessions[] = $session;
671
                    if (isset($session['id'])) {
672
                        $childSessions = array_filter($sessions, fn($s) => isset($s['parent_id']) && $s['parent_id'] === $session['id']);
673
                        foreach ($childSessions as $childSession) {
674
                            $childSession['title'] = '-- ' . $childSession['title'];
675
                            $formattedSessions[] = $childSession;
676
                        }
677
                    }
678
                }
679
680
                return $formattedSessions;
681
            }
682
683
            if ('all' === $listType) {
684
                if ($getCount) {
685
                    return $sessions[0]['total_rows'];
686
                }
687
                return $sessions;
688
            }
689
            return $sessions;
690
        }
691
692
        // For search diagnosis format (Ofaj)
693
        $categories = self::get_all_session_category();
694
        $orderedCategories = [];
695
        if (!empty($categories)) {
696
            foreach ($categories as $category) {
697
                $orderedCategories[$category['id']] = $category['title'];
698
            }
699
        }
700
        $result = Database::query($query);
701
        $formattedSessions = [];
702
        if (Database::num_rows($result)) {
703
            $sessions = Database::store_result($result, 'ASSOC');
704
            if ($getCount) {
705
                return $sessions[0]['total_rows'];
706
            }
707
708
            $activeIcon = Display::getMdiIcon(StateIcon::ACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Active'));
709
            $inactiveIcon = Display::getMdiIcon(StateIcon::INACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Inactive'));
710
711
            foreach ($sessions as $session) {
712
                $session_id = $session['id'];
713
                if ($showCountUsers) {
714
                    $session['users'] = self::get_users_by_session(
715
                        $session['id'],
716
                        0,
717
                        true
718
                    );
719
                    $usersLang = self::getCountUsersLangBySession($session['id'], api_get_current_access_url_id(), Session::STUDENT);
720
                    $tooltipUserLangs = '';
721
                    if (!empty($usersLang)) {
722
                        $tooltipUserLangs = implode(' | ', $usersLang);
723
                    }
724
                    $session['users'] = '<a href="#" title="'.$tooltipUserLangs.'">'.$session['users'].'</a>';
725
                    $courses = self::getCoursesInSession($session_id);
726
                    $teachers = '';
727
                    foreach ($courses as $courseId) {
728
                        $courseInfo = api_get_course_info_by_id($courseId);
729
730
                        // Ofaj
731
                        $teachers = CourseManager::get_coachs_from_course_to_string($session_id, $courseInfo['real_id']);
732
                    }
733
                    // ofaj
734
                    $session['teachers'] = '';
735
                    if (!empty($teachers)) {
736
                        $session['teachers'] = Display::getMdiIcon(ObjectIcon::TEACHER, 'ch-tool-icon', null, ICON_SIZE_SMALL, addslashes($teachers));
737
                    }
738
                }
739
                $url = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session['id'];
740
                if (api_is_drh()) {
741
                    $url = api_get_path(WEB_CODE_PATH).'session/about.php?session_id='.$session['id'];
742
                }
743
                if (api_is_platform_admin()) {
744
                    $url = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session['id'];
745
                }
746
747
                if ($extraFieldsToLoad) {
748
                    $url = api_get_path(WEB_CODE_PATH).'session/about.php?session_id='.$session['id'];
749
                }
750
                $session['title'] = Display::url($session['title'], $url);
751
752
                if (isset($session['session_active']) && $session['session_active'] == 1) {
753
                    $session['session_active'] = $activeIcon;
754
                } else {
755
                    $session['session_active'] = $inactiveIcon;
756
                }
757
758
                $session = self::convert_dates_to_local($session, true);
759
760
                switch ($session['visibility']) {
761
                    case SESSION_VISIBLE_READ_ONLY: //1
762
                        $session['visibility'] = get_lang('Read only');
763
                        break;
764
                    case SESSION_VISIBLE:           //2
765
                    case SESSION_AVAILABLE:         //4
766
                        $session['visibility'] = get_lang('Visible');
767
                        break;
768
                    case SESSION_INVISIBLE:         //3
769
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
770
                        break;
771
                }
772
773
                if (!empty($extraFieldsToLoad)) {
774
                    foreach ($extraFieldsToLoad as $field) {
775
                        $extraFieldValue = new ExtraFieldValue('session');
776
                        $fieldData = $extraFieldValue->getAllValuesByItemAndField(
777
                            $session['id'],
778
                            $field['id']
779
                        );
780
                        $fieldDataArray = [];
781
                        $fieldDataToString = '';
782
                        if (!empty($fieldData)) {
783
                            foreach ($fieldData as $data) {
784
                                $fieldDataArray[] = $data['field_value'];
785
                            }
786
                            $fieldDataToString = implode(', ', $fieldDataArray);
787
                        }
788
                        $session[$field['variable']] = $fieldDataToString;
789
                    }
790
                }
791
792
                $categoryName = $orderedCategories[$session['session_category_id']] ?? '';
793
                $session['category_name'] = $categoryName;
794
                if (isset($session['status'])) {
795
                    $session['status'] = self::getStatusLabel($session['status']);
796
                }
797
798
                $formattedSessions[] = $session;
799
            }
800
        }
801
802
        return $formattedSessions;
803
    }
804
805
    /**
806
     * Get the count of users by language and session
807
     *
808
     * @param $sid
809
     * @param int $urlId
810
     * @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...
811
     *
812
     * @return array A list of ISO lang of users registered in the session , ex: FR 6
813
     */
814
    public static function getCountUsersLangBySession(
815
        $sid,
816
        $urlId = 0,
817
        $status = null
818
    ): array
819
    {
820
        $sid = (int) $sid;
821
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
822
823
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
824
        $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
825
        $tableAccessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
826
        $tableLanguage = Database::get_main_table(TABLE_MAIN_LANGUAGE);
827
828
        $sql = "SELECT l.isocode, count(u.id) as cLang
829
                FROM $tblSessionUser su
830
                INNER JOIN $tblUser u ON (u.id = su.user_id)
831
                INNER JOIN $tableLanguage l ON (l.isocode = u.locale)
832
                LEFT OUTER JOIN $tableAccessUrlUser au ON (au.user_id = u.id)
833
                ";
834
835
        if (is_numeric($status)) {
836
            $status = (int) $status;
837
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
838
        } else {
839
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
840
        }
841
        $sql .= " AND su.session_id = $sid GROUP BY l.isocode";
842
843
        $rs = Database::query($sql);
844
        $usersLang = [];
845
        if (Database::num_rows($rs) > 0) {
846
            while ($row = Database::fetch_assoc($rs)) {
847
                $usersLang[] = strtoupper($row['isocode'])." ".$row['cLang'];
848
            }
849
        }
850
851
        return $usersLang;
852
    }
853
854
    /**
855
     * Gets the admin session list callback of the session/session_list.php page.
856
     *
857
     * @param array  $options           order and limit keys
858
     * @param bool   $getCount          Whether to get all the results or only the count
859
     * @param array  $columns
860
     * @param array  $extraFieldsToLoad
861
     * @param string $listType
862
     *
863
     * @return mixed Integer for number of rows, or array of results
864
     * @assert ([],true) !== false
865
     */
866
    public static function formatSessionsAdminForGrid(
867
        $options = [],
868
        $getCount = false,
869
        $columns = [],
870
        $extraFieldsToLoad = [],
871
        $listType = 'all'
872
    ) {
873
        $showCountUsers = false;
874
        if (!$getCount && !empty($columns['column_model'])) {
875
            foreach ($columns['column_model'] as $column) {
876
                if ('users' === $column['name']) {
877
                    $showCountUsers = true;
878
                }
879
            }
880
        }
881
882
        $userId = api_get_user_id();
883
        $sessions = self::getSessionsForAdmin($userId, $options, $getCount, $columns, $listType, $extraFieldsToLoad);
884
        if ($getCount) {
885
            return (int) $sessions;
886
        }
887
888
        $formattedSessions = [];
889
        $categories = self::get_all_session_category();
890
        $orderedCategories = [];
891
        if (!empty($categories)) {
892
            foreach ($categories as $category) {
893
                $orderedCategories[$category['id']] = $category['title'];
894
            }
895
        }
896
897
        $activeIcon = Display::getMdiIcon(StateIcon::ACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Active'));
898
        $inactiveIcon = Display::getMdiIcon(StateIcon::INACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Inactive'));
899
900
        foreach ($sessions as $session) {
901
            if ($showCountUsers) {
902
                $session['users'] = self::get_users_by_session($session['id'], 0, true);
903
            }
904
            $url = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session['id'];
905
            if ($extraFieldsToLoad || api_is_drh()) {
906
                $url = api_get_path(WEB_PATH).'sessions/'.$session['id'].'/about/';
907
            }
908
909
            $session['title'] = Display::url($session['title'], $url);
910
911
            if (!empty($extraFieldsToLoad)) {
912
                foreach ($extraFieldsToLoad as $field) {
913
                    $extraFieldValue = new ExtraFieldValue('session');
914
                    $fieldData = $extraFieldValue->getAllValuesByItemAndField(
915
                        $session['id'],
916
                        $field['id']
917
                    );
918
                    $fieldDataArray = [];
919
                    $fieldDataToString = '';
920
                    if (!empty($fieldData)) {
921
                        foreach ($fieldData as $data) {
922
                            $fieldDataArray[] = $data['field_value'];
923
                        }
924
                        $fieldDataToString = implode(', ', $fieldDataArray);
925
                    }
926
                    $session[$field['variable']] = $fieldDataToString;
927
                }
928
            }
929
930
            if (isset($session['session_active']) && 1 == $session['session_active']) {
931
                $session['session_active'] = $activeIcon;
932
            } else {
933
                $session['session_active'] = $inactiveIcon;
934
            }
935
936
            $session = self::convert_dates_to_local($session, true);
937
938
            switch ($session['visibility']) {
939
                case SESSION_VISIBLE_READ_ONLY: //1
940
                    $session['visibility'] = get_lang('Read only');
941
                    break;
942
                case SESSION_VISIBLE:           //2
943
                case SESSION_AVAILABLE:         //4
944
                    $session['visibility'] = get_lang('Visible');
945
                    break;
946
                case SESSION_INVISIBLE:         //3
947
                    $session['visibility'] = api_ucfirst(get_lang('Invisible'));
948
                    break;
949
            }
950
951
            // Cleaning double selects.
952
            foreach ($session as $key => &$value) {
953
                /*if (isset($optionsByDouble[$key]) || isset($optionsByDouble[$key.'_second'])) {
954
                    $options = explode('::', $value);
955
                }*/
956
                $original_key = $key;
957
                if (false !== strpos($key, '_second')) {
958
                    $key = str_replace('_second', '', $key);
959
                }
960
961
                /*if (isset($optionsByDouble[$key]) &&
962
                    isset($options[0]) &&
963
                    isset($optionsByDouble[$key][$options[0]])
964
                ) {
965
                    if (false === strpos($original_key, '_second')) {
966
                        $value = $optionsByDouble[$key][$options[0]]['option_display_text'];
967
                    } else {
968
                        $value = $optionsByDouble[$key][$options[1]]['option_display_text'];
969
                    }
970
                }*/
971
            }
972
973
            $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
974
            $session['category_name'] = $categoryName;
975
            if (isset($session['status'])) {
976
                $session['status'] = self::getStatusLabel($session['status']);
977
            }
978
979
            $formattedSessions[] = $session;
980
        }
981
982
        return $formattedSessions;
983
    }
984
985
    /**
986
     * Gets the progress of learning paths in the given session.
987
     *
988
     * @param int    $sessionId
989
     * @param int    $courseId
990
     * @param string $date_from
991
     * @param string $date_to
992
     * @param array options order and limit keys
993
     *
994
     * @return array table with user name, lp name, progress
995
     */
996
    public static function get_session_lp_progress(
997
        $sessionId,
998
        $courseId,
999
        $date_from,
1000
        $date_to,
1001
        $options
1002
    ) {
1003
        //escaping vars
1004
        $sessionId = $sessionId === 'T' ? 'T' : intval($sessionId);
1005
        $courseId = intval($courseId);
1006
1007
        //tables
1008
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1009
        $user = Database::get_main_table(TABLE_MAIN_USER);
1010
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
1011
1012
        $course = api_get_course_info_by_id($courseId);
1013
        $sessionCond = 'and session_id = %s';
1014
        if ($sessionId === 'T') {
1015
            $sessionCond = '';
1016
        }
1017
1018
        $where = " WHERE c_id = '%s' AND s.status = ".Session::STUDENT." $sessionCond";
1019
1020
        $limit = null;
1021
        if (!empty($options['limit'])) {
1022
            $limit = " LIMIT ".$options['limit'];
1023
        }
1024
1025
        if (!empty($options['where'])) {
1026
            $where .= ' '.$options['where'];
1027
        }
1028
1029
        $order = null;
1030
        if (!empty($options['order'])) {
1031
            $order = " ORDER BY ".$options['order']." ";
1032
        }
1033
1034
        $sql = "SELECT u.id as user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
1035
                FROM $session_course_user s
1036
                INNER JOIN $user u ON u.id = s.user_id
1037
                $where
1038
                $order
1039
                $limit";
1040
1041
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
1042
1043
        $rs = Database::query($sql_query);
1044
        while ($user = Database::fetch_array($rs)) {
1045
            $users[$user['user_id']] = $user;
1046
        }
1047
1048
        // Get lessons
1049
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
1050
1051
        $table = [];
1052
        foreach ($users as $user) {
1053
            $data = [
1054
                'lastname' => $user[1],
1055
                'firstname' => $user[2],
1056
                'username' => $user[3],
1057
            ];
1058
1059
            $sessionCond = 'AND v.session_id = %d';
1060
            if ($sessionId == 'T') {
1061
                $sessionCond = "";
1062
            }
1063
1064
            //Get lessons progress by user
1065
            $sql = "SELECT v.lp_id as id, v.progress
1066
                    FROM  $tbl_course_lp_view v
1067
                    WHERE v.c_id = %d
1068
                    AND v.user_id = %d
1069
            $sessionCond";
1070
1071
            $sql_query = sprintf(
1072
                $sql,
1073
                intval($courseId),
1074
                intval($user['user_id']),
1075
                $sessionId
1076
            );
1077
1078
            $result = Database::query($sql_query);
1079
1080
            $user_lessons = [];
1081
            while ($row = Database::fetch_array($result)) {
1082
                $user_lessons[$row['id']] = $row;
1083
            }
1084
1085
            //Match course lessons with user progress
1086
            $progress = 0;
1087
            $count = 0;
1088
            foreach ($lessons as $lesson) {
1089
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
1090
                $progress += $data[$lesson['id']];
1091
                $data[$lesson['id']] = $data[$lesson['id']].'%';
1092
                $count++;
1093
            }
1094
            if (0 == $count) {
1095
                $data['total'] = 0;
1096
            } else {
1097
                $data['total'] = round($progress / $count, 2).'%';
1098
            }
1099
            $table[] = $data;
1100
        }
1101
1102
        return $table;
1103
    }
1104
1105
    /**
1106
     * Gets the survey answers.
1107
     *
1108
     * @param int $sessionId
1109
     * @param int $courseId
1110
     * @param int $surveyId
1111
     * @param array options order and limit keys
1112
     *
1113
     * @todo fix the query
1114
     *
1115
     * @return array table with username, lp name, progress
1116
     */
1117
    public static function get_survey_overview(
1118
        $sessionId,
1119
        $courseId,
1120
        $surveyId,
1121
        $date_from,
1122
        $date_to,
1123
        $options
1124
    ) {
1125
        $sessionId = (int) $sessionId;
1126
        $courseId = (int) $courseId;
1127
        $surveyId = (int) $surveyId;
1128
1129
        //tables
1130
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1131
        $user = Database::get_main_table(TABLE_MAIN_USER);
1132
        $c_survey = Database::get_course_table(TABLE_SURVEY);
1133
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
1134
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
1135
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
1136
1137
        $course = api_get_course_info_by_id($courseId);
1138
1139
        $where = " WHERE c_id = '%s' AND s.status = ".Session::STUDENT." AND session_id = %s";
1140
1141
        $limit = null;
1142
        if (!empty($options['limit'])) {
1143
            $limit = " LIMIT ".$options['limit'];
1144
        }
1145
1146
        if (!empty($options['where'])) {
1147
            $where .= ' '.$options['where'];
1148
        }
1149
1150
        $order = null;
1151
        if (!empty($options['order'])) {
1152
            $order = " ORDER BY ".$options['order'];
1153
        }
1154
1155
        $sql = "SELECT u.id as user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
1156
                FROM $session_course_user s
1157
                INNER JOIN $user u ON u.id = s.user_id
1158
                $where $order $limit";
1159
1160
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
1161
        $rs = Database::query($sql_query);
1162
        while ($user = Database::fetch_array($rs)) {
1163
            $users[$user['user_id']] = $user;
1164
        }
1165
        $repo = Container::getSurveyRepository();
1166
        /** @var CSurvey $survey */
1167
        $survey = $repo->find($surveyId);
1168
        $questions = $survey->getQuestions();
1169
        $anonymous = (1 == $survey->getAnonymous()) ? true : false;
1170
1171
        $table = [];
1172
        foreach ($users as $user) {
1173
            $data = [
1174
                'lastname' => ($anonymous ? '***' : $user[1]),
1175
                'firstname' => ($anonymous ? '***' : $user[2]),
1176
                'username' => ($anonymous ? '***' : $user[3]),
1177
            ];
1178
1179
            //Get questions by user
1180
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
1181
                    FROM $c_survey_answer sa
1182
                    INNER JOIN $c_survey_question sq
1183
                    ON sq.question_id = sa.question_id
1184
                    LEFT JOIN $c_survey_question_option sqo
1185
                    ON
1186
                      sqo.c_id = sa.c_id AND
1187
                      sqo.question_id = sq.question_id AND
1188
                      sqo.iid = sa.option_id AND
1189
                      sqo.survey_id = sq.survey_id
1190
                    WHERE
1191
                      sa.survey_id = %d AND
1192
                      sa.c_id = %d AND
1193
                      sa.user = %d
1194
            "; //. $where_survey;
1195
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
1196
            $result = Database::query($sql_query);
1197
            $user_questions = [];
1198
            while ($row = Database::fetch_array($result)) {
1199
                $user_questions[$row['question_id']] = $row;
1200
            }
1201
1202
            //Match course lessons with user progress
1203
            foreach ($questions as $question) {
1204
                $questionId = $question->getIid();
1205
                $option_text = 'option_text';
1206
                if ('open' === $user_questions[$questionId]['type']) {
1207
                    $option_text = 'option_id';
1208
                }
1209
                $data[$questionId] = $user_questions[$questionId][$option_text];
1210
            }
1211
            $table[] = $data;
1212
        }
1213
1214
        return $table;
1215
    }
1216
1217
    /**
1218
     * Gets the progress of the given session.
1219
     *
1220
     * @param int $sessionId
1221
     * @param int $courseId
1222
     * @param array options order and limit keys
1223
     *
1224
     * @return array table with username, lp name, progress
1225
     */
1226
    public static function get_session_progress(
1227
        $sessionId,
1228
        $courseId,
1229
        $date_from,
1230
        $date_to,
1231
        $options
1232
    ) {
1233
        $sessionId = (int) $sessionId;
1234
1235
        $getAllSessions = false;
1236
        if (empty($sessionId)) {
1237
            $sessionId = 0;
1238
            $getAllSessions = true;
1239
        }
1240
1241
        //tables
1242
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1243
        $user = Database::get_main_table(TABLE_MAIN_USER);
1244
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1245
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1246
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
1247
        $wiki = Database::get_course_table(TABLE_WIKI);
1248
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
1249
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1250
1251
        $course = api_get_course_info_by_id($courseId);
1252
        $where = " WHERE c_id = '%s' AND s.status = ".Session::STUDENT;
1253
1254
        $limit = null;
1255
        if (!empty($options['limit'])) {
1256
            $limit = " LIMIT ".$options['limit'];
1257
        }
1258
1259
        if (!empty($options['where'])) {
1260
            $where .= ' '.$options['where'];
1261
        }
1262
1263
        $order = null;
1264
        if (!empty($options['order'])) {
1265
            $order = " ORDER BY ".$options['order'];
1266
        }
1267
1268
        //TODO, fix create report without session
1269
        $queryVariables = [$course['real_id']];
1270
        if (!empty($sessionId)) {
1271
            $where .= ' AND session_id = %s';
1272
            $queryVariables[] = $sessionId;
1273
            $sql = "SELECT
1274
                        u.id as user_id, u.lastname, u.firstname, u.username,
1275
                        u.email, s.c_id, s.session_id
1276
                    FROM $session_course_user s
1277
                    INNER JOIN $user u
1278
                    ON u.id = s.user_id
1279
                    $where $order $limit";
1280
        } else {
1281
            $sql = "SELECT
1282
                        u.id as user_id, u.lastname, u.firstname, u.username,
1283
                        u.email, s.c_id, s.session_id
1284
                    FROM $session_course_user s
1285
                    INNER JOIN $user u ON u.id = s.user_id
1286
                    $where $order $limit";
1287
        }
1288
1289
        $sql_query = vsprintf($sql, $queryVariables);
1290
        $rs = Database::query($sql_query);
1291
        while ($user = Database::fetch_array($rs)) {
1292
            $users[$user['user_id']] = $user;
1293
        }
1294
1295
        /**
1296
         *  Lessons.
1297
         */
1298
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s "; //AND session_id = %s
1299
        $sql_query = sprintf($sql, $course['real_id']);
1300
        $result = Database::query($sql_query);
1301
        $arrLesson = [[]];
1302
        while ($row = Database::fetch_array($result)) {
1303
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
1304
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
1305
            } else {
1306
                $arrLesson[$row['session_id']]['lessons_total']++;
1307
            }
1308
        }
1309
        $session = api_get_session_entity($sessionId);
1310
        $qb = Container::getQuizRepository()->findAllByCourse($course, $session, null, 2);
1311
        $exercises = $qb->getQuery()->getResult();
1312
        $exercises_total = count($exercises);
1313
1314
        /*$exercises = ExerciseLib::get_all_exercises(
1315
            $course,
1316
            $sessionId,
1317
            false,
1318
            '',
1319
            $getAllSessions
1320
        );
1321
        $exercises_total = count($exercises);*/
1322
1323
        /**
1324
         *  Assignments.
1325
         */
1326
        //total
1327
        $params = [$course['real_id']];
1328
        if ($getAllSessions) {
1329
            $sql = "SELECT count(w.id) as count
1330
                    FROM $workTable w
1331
                    LEFT JOIN $workTableAssignment a
1332
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1333
                    WHERE
1334
                        w.c_id = %s AND
1335
                        parent_id = 0 AND
1336
                        active IN (1, 0)";
1337
        } else {
1338
            $sql = "SELECT count(w.id) as count
1339
                    FROM $workTable w
1340
                    LEFT JOIN $workTableAssignment a
1341
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1342
                    WHERE
1343
                        w.c_id = %s AND
1344
                        parent_id = 0 AND
1345
                        active IN (1, 0)";
1346
1347
            if (empty($sessionId)) {
1348
                $sql .= ' AND w.session_id = NULL ';
1349
            } else {
1350
                $sql .= ' AND w.session_id = %s ';
1351
                $params[] = $sessionId;
1352
            }
1353
        }
1354
1355
        $sql_query = vsprintf($sql, $params);
1356
        $result = Database::query($sql_query);
1357
        $row = Database::fetch_array($result);
1358
        $assignments_total = $row['count'];
1359
1360
        /**
1361
         * Wiki.
1362
         */
1363
        if ($getAllSessions) {
1364
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1365
                    WHERE c_id = %s";
1366
        } else {
1367
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1368
                    WHERE c_id = %s and session_id = %s";
1369
        }
1370
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
1371
        $result = Database::query($sql_query);
1372
        $row = Database::fetch_array($result);
1373
        $wiki_total = $row['count'];
1374
1375
        /**
1376
         * Surveys.
1377
         */
1378
        $survey_user_list = [];
1379
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
1380
1381
        $surveys_total = count($survey_list);
1382
        foreach ($survey_list as $survey) {
1383
            $user_list = SurveyManager::get_people_who_filled_survey(
1384
                $survey['survey_id'],
1385
                false,
1386
                $course['real_id']
1387
            );
1388
            foreach ($user_list as $user_id) {
1389
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id]++ : $survey_user_list[$user_id] = 1;
1390
            }
1391
        }
1392
1393
        /**
1394
         * Forums.
1395
         */
1396
        $forums_total = CourseManager::getCountForum(
1397
            $course['real_id'],
1398
            $sessionId,
1399
            $getAllSessions
1400
        );
1401
1402
        //process table info
1403
        foreach ($users as $user) {
1404
            //Course description
1405
            $sql = "SELECT count(*) as count
1406
                    FROM $table_stats_access
1407
                    WHERE access_tool = 'course_description'
1408
                    AND c_id = '%s'
1409
                    AND session_id = %s
1410
                    AND access_user_id = %s ";
1411
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1412
1413
            $result = Database::query($sql_query);
1414
            $row = Database::fetch_array($result);
1415
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1416
1417
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1418
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1419
            } else {
1420
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1421
            }
1422
1423
            //Lessons
1424
            //TODO: Lessons done and left is calculated by progress per item in lesson,
1425
            // maybe we should calculate it only per completed lesson?
1426
            $lessons_progress = Tracking::get_avg_student_progress(
1427
                $user['user_id'],
1428
                $course['code'],
1429
                [],
1430
                $user['id_session']
1431
            );
1432
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1433
            $lessons_left = $lessons_total - $lessons_done;
1434
1435
            // Exercises
1436
            $exercises_progress = str_replace(
1437
                '%',
1438
                '',
1439
                Tracking::get_exercise_student_progress(
1440
                    $exercises,
1441
                    $user['user_id'],
1442
                    $course['real_id'],
1443
                    $user['id_session']
1444
                )
1445
            );
1446
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1447
            $exercises_left = $exercises_total - $exercises_done;
1448
1449
            //Assignments
1450
            $assignments_done = Container::getStudentPublicationRepository()->countUserPublications(
1451
                $user['user_id'],
1452
                $course['code'],
1453
                $user['id_session']
1454
            );
1455
            $assignments_left = $assignments_total - $assignments_done;
1456
            if (!empty($assignments_total)) {
1457
                $assignments_progress = round((($assignments_done * 100) / $assignments_total), 2);
1458
            } else {
1459
                $assignments_progress = 0;
1460
            }
1461
1462
            // Wiki
1463
            // total revisions per user
1464
            $sql = "SELECT count(*) as count
1465
                    FROM $wiki
1466
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1467
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1468
            $result = Database::query($sql_query);
1469
            $row = Database::fetch_array($result);
1470
            $wiki_revisions = $row['count'];
1471
            //count visited wiki pages
1472
            $sql = "SELECT count(distinct default_value) as count
1473
                    FROM $table_stats_default
1474
                    WHERE
1475
                        default_user_id = %s AND
1476
                        default_event_type = 'wiki_page_view' AND
1477
                        default_value_type = 'wiki_page_id' AND
1478
                        c_id = %s
1479
                    ";
1480
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1481
            $result = Database::query($sql_query);
1482
            $row = Database::fetch_array($result);
1483
1484
            $wiki_read = $row['count'];
1485
            $wiki_unread = $wiki_total - $wiki_read;
1486
            if (!empty($wiki_total)) {
1487
                $wiki_progress = round((($wiki_read * 100) / $wiki_total), 2);
1488
            } else {
1489
                $wiki_progress = 0;
1490
            }
1491
1492
            // Surveys
1493
            $surveys_done = isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0;
1494
            $surveys_left = $surveys_total - $surveys_done;
1495
            if (!empty($surveys_total)) {
1496
                $surveys_progress = round((($surveys_done * 100) / $surveys_total), 2);
1497
            } else {
1498
                $surveys_progress = 0;
1499
            }
1500
1501
            //Forums
1502
            $forums_done = CourseManager::getCountForumPerUser(
1503
                $user['user_id'],
1504
                $course['real_id'],
1505
                $user['id_session']
1506
            );
1507
            $forums_left = $forums_total - $forums_done;
1508
            if (!empty($forums_total)) {
1509
                $forums_progress = round((($forums_done * 100) / $forums_total), 2);
1510
            } else {
1511
                $forums_progress = 0;
1512
            }
1513
1514
            // Overall Total
1515
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1516
1517
            $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>';
1518
            $linkForum = '<a href="'.api_get_path(WEB_CODE_PATH).'forum/index.php?cid='.$course['real_id'].'&sid='.$sessionId.'"> %s </a>';
1519
            $linkWork = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?cid='.$course['real_id'].'&sid='.$sessionId.'"> %s </a>';
1520
            $linkWiki = '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?cid='.$course['real_id'].'&sid='.$sessionId.'&action=statistics"> %s </a>';
1521
            $linkSurvey = '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?cid='.$course['real_id'].'&sid='.$sessionId.'"> %s </a>';
1522
1523
            $table[] = [
1524
                'lastname' => $user[1],
1525
                'firstname' => $user[2],
1526
                'username' => $user[3],
1527
                //'profile'   => '',
1528
                'total' => round($overall_total, 2).'%',
1529
                'courses' => sprintf($link, $course_description_progress.'%'),
1530
                'lessons' => sprintf($link, $lessons_progress.'%'),
1531
                'exercises' => sprintf($link, $exercises_progress.'%'),
1532
                'forums' => sprintf($link, $forums_progress.'%'),
1533
                'homeworks' => sprintf($link, $assignments_progress.'%'),
1534
                'wikis' => sprintf($link, $wiki_progress.'%'),
1535
                'surveys' => sprintf($link, $surveys_progress.'%'),
1536
                //course description
1537
                'course_description_progress' => $course_description_progress.'%',
1538
                //lessons
1539
                'lessons_total' => sprintf($link, $lessons_total),
1540
                'lessons_done' => sprintf($link, $lessons_done),
1541
                'lessons_left' => sprintf($link, $lessons_left),
1542
                'lessons_progress' => sprintf($link, $lessons_progress.'%'),
1543
                //exercises
1544
                'exercises_total' => sprintf($link, $exercises_total),
1545
                'exercises_done' => sprintf($link, $exercises_done),
1546
                'exercises_left' => sprintf($link, $exercises_left),
1547
                'exercises_progress' => sprintf($link, $exercises_progress.'%'),
1548
                //forums
1549
                'forums_total' => sprintf($linkForum, $forums_total),
1550
                'forums_done' => sprintf($linkForum, $forums_done),
1551
                'forums_left' => sprintf($linkForum, $forums_left),
1552
                'forums_progress' => sprintf($linkForum, $forums_progress.'%'),
1553
                //assignments
1554
                'assignments_total' => sprintf($linkWork, $assignments_total),
1555
                'assignments_done' => sprintf($linkWork, $assignments_done),
1556
                'assignments_left' => sprintf($linkWork, $assignments_left),
1557
                'assignments_progress' => sprintf($linkWork, $assignments_progress.'%'),
1558
                //wiki
1559
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1560
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1561
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1562
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1563
                'wiki_progress' => sprintf($linkWiki, $wiki_progress.'%'),
1564
                //survey
1565
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1566
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1567
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1568
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress.'%'),
1569
            ];
1570
        }
1571
1572
        return $table;
1573
    }
1574
1575
    /**
1576
     * Get the ip, total of clicks, login date and time logged in for all user, in one session.
1577
     *
1578
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1579
     *
1580
     * @author César Perales <[email protected]>, Beeznest Team
1581
     *
1582
     * @version 1.9.6
1583
     */
1584
    public static function get_user_data_access_tracking_overview(
1585
        $sessionId,
1586
        $courseId,
1587
        $studentId = 0,
1588
        $profile = '',
1589
        $date_from = '',
1590
        $date_to = '',
1591
        $options = []
1592
    ) {
1593
        $sessionId = intval($sessionId);
1594
        $courseId = intval($courseId);
1595
        $studentId = intval($studentId);
1596
        $profile = intval($profile);
1597
        $date_from = Database::escape_string($date_from);
1598
        $date_to = Database::escape_string($date_to);
1599
1600
        // database table definition
1601
        $user = Database::get_main_table(TABLE_MAIN_USER);
1602
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
1603
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1604
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1605
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1606
1607
        global $export_csv;
1608
        if ($export_csv) {
1609
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1610
        } else {
1611
            $is_western_name_order = api_is_western_name_order();
1612
        }
1613
1614
        $where = null;
1615
        if (isset($sessionId) && !empty($sessionId)) {
1616
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1617
        }
1618
        if (isset($courseId) && !empty($courseId)) {
1619
            $where .= sprintf(" AND c.id = %d", $courseId);
1620
        }
1621
        if (isset($studentId) && !empty($studentId)) {
1622
            $where .= sprintf(" AND u.id = %d", $studentId);
1623
        }
1624
        if (isset($profile) && !empty($profile)) {
1625
            $where .= sprintf(" AND u.status = %d", $profile);
1626
        }
1627
        if (!empty($date_to) && !empty($date_from)) {
1628
            $where .= sprintf(
1629
                " AND a.login_course_date >= '%s 00:00:00'
1630
                 AND a.login_course_date <= '%s 23:59:59'",
1631
                $date_from,
1632
                $date_to
1633
            );
1634
        }
1635
1636
        $limit = null;
1637
        if (!empty($options['limit'])) {
1638
            $limit = " LIMIT ".$options['limit'];
1639
        }
1640
1641
        if (!empty($options['where'])) {
1642
            $where .= ' '.$options['where'];
1643
        }
1644
1645
        $order = null;
1646
        if (!empty($options['order'])) {
1647
            $order = " ORDER BY ".$options['order'];
1648
        }
1649
1650
        //TODO add course name
1651
        $sql = "SELECT
1652
                a.login_course_date ,
1653
                u.username ,
1654
                ".($is_western_name_order ? "
1655
                    u.firstname,
1656
                    u.lastname,
1657
                    " : "
1658
                    u.lastname,
1659
                    u.firstname,
1660
                ")."
1661
                a.logout_course_date,
1662
                a.counter,
1663
                c.title,
1664
                c.code,
1665
                u.id as user_id,
1666
                a.session_id
1667
            FROM $track_e_course_access a
1668
            INNER JOIN $user u ON a.user_id = u.id
1669
            INNER JOIN $course c ON a.c_id = c.id
1670
            $where $order $limit";
1671
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1672
1673
        $data = [];
1674
        while ($user = Database::fetch_assoc($result)) {
1675
            $data[] = $user;
1676
        }
1677
1678
        foreach ($data as $key => $info) {
1679
            $sql = "SELECT
1680
                    title
1681
                    FROM $sessionTable
1682
                    WHERE
1683
                    id = {$info['session_id']}";
1684
            $result = Database::query($sql);
1685
            $session = Database::fetch_assoc($result);
1686
1687
            // building array to display
1688
            $return[] = [
1689
                'user_id' => $info['user_id'],
1690
                'logindate' => $info['login_course_date'],
1691
                'username' => $info['username'],
1692
                'firstname' => $info['firstname'],
1693
                'lastname' => $info['lastname'],
1694
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1695
                'ip' => '',
1696
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1697
                'session' => $session['title'],
1698
            ];
1699
        }
1700
1701
        foreach ($return as $key => $info) {
1702
            //Search for ip, we do less querys if we iterate the final array
1703
            $sql = sprintf(
1704
                "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1",
1705
                $info['user_id'],
1706
                $info['logindate']
1707
            ); //TODO add select by user too
1708
            $result = Database::query($sql);
1709
            $ip = Database::fetch_assoc($result);
1710
            //if no ip founded, we search the closest higher ip
1711
            if (empty($ip['user_ip'])) {
1712
                $sql = sprintf(
1713
                    "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1",
1714
                    $info['user_id'],
1715
                    $info['logindate']
1716
                ); //TODO add select by user too
1717
                $result = Database::query($sql);
1718
                $ip = Database::fetch_assoc($result);
1719
            }
1720
            //add ip to final array
1721
            $return[$key]['ip'] = $ip['user_ip'];
1722
        }
1723
1724
        return $return;
1725
    }
1726
1727
    /**
1728
     * Creates a new course code based in given code.
1729
     *
1730
     * @param string $session_name
1731
     *                             <code>
1732
     *                             $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1733
     *                             if the course code doest not exist in the DB the same course code will be returned
1734
     *                             </code>
1735
     *
1736
     * @return string wanted unused code
1737
     */
1738
    public static function generateNextSessionName($session_name)
1739
    {
1740
        $session_name_ok = !self::sessionNameExists($session_name);
1741
        if (!$session_name_ok) {
1742
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1743
            $session_name = Database::escape_string($session_name);
1744
            $sql = "SELECT count(*) as count FROM $table
1745
                    WHERE title LIKE '$session_name%'";
1746
            $result = Database::query($sql);
1747
            if (Database::num_rows($result) > 0) {
1748
                $row = Database::fetch_array($result);
1749
                $count = $row['count'] + 1;
1750
                $session_name = $session_name.'_'.$count;
1751
                $result = self::sessionNameExists($session_name);
1752
                if (!$result) {
1753
                    return $session_name;
1754
                }
1755
            }
1756
1757
            return false;
1758
        }
1759
1760
        return $session_name;
1761
    }
1762
1763
    /**
1764
     * Edit a session.
1765
     *
1766
     * @author Carlos Vargas from existing code
1767
     *
1768
     * @param int    $id                           Session primary key
1769
     * @param string $name
1770
     * @param string $startDate
1771
     * @param string $endDate
1772
     * @param string $displayStartDate
1773
     * @param string $displayEndDate
1774
     * @param string $coachStartDate
1775
     * @param string $coachEndDate
1776
     * @param array  $coachesId
1777
     * @param int    $sessionCategoryId
1778
     * @param int    $visibility
1779
     * @param string $description
1780
     * @param int    $showDescription
1781
     * @param int    $duration
1782
     * @param array  $extraFields
1783
     * @param int    $sessionAdminId
1784
     * @param bool   $sendSubscriptionNotification Optional. Whether send a mail notification to users being subscribed
1785
     * @param int    $status
1786
     *
1787
     * @return mixed
1788
     */
1789
    public static function edit_session(
1790
        $id,
1791
        $name,
1792
        $startDate,
1793
        $endDate,
1794
        $displayStartDate,
1795
        $displayEndDate,
1796
        $coachStartDate,
1797
        $coachEndDate,
1798
        $coachesId,
1799
        $sessionCategoryId,
1800
        $visibility,
1801
        $description = null,
1802
        $showDescription = 0,
1803
        $duration = 0,
1804
        $extraFields = [],
1805
        $sessionAdminId = 0,
1806
        $sendSubscriptionNotification = false,
1807
        $status = 0,
1808
        $notifyBoss = 0,
1809
        $parentId = 0,
1810
        $daysBeforeFinishingForReinscription = null,
1811
        $daysBeforeFinishingToCreateNewRepetition = null,
1812
        $lastRepetition = false,
1813
        $validityInDays = null
1814
    ) {
1815
        $id = (int) $id;
1816
        $status = (int) $status;
1817
        $coachesId = array_map(fn($id) => (int) $id, $coachesId);
1818
        $sessionCategoryId = (int) $sessionCategoryId;
1819
        $visibility = (int) $visibility;
1820
        $duration = (int) $duration;
1821
1822
        $em = Database::getManager();
1823
1824
        if (empty($name)) {
1825
            Display::addFlash(
1826
                Display::return_message(get_lang('A name is required for the session'), 'warning')
1827
            );
1828
1829
            return false;
1830
        } elseif (empty($coachesId)) {
1831
            Display::addFlash(
1832
                Display::return_message(get_lang('You must select a coach'), 'warning')
1833
            );
1834
1835
            return false;
1836
        } elseif (!empty($startDate) &&
1837
            !api_is_valid_date($startDate, 'Y-m-d H:i') &&
1838
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
1839
        ) {
1840
            Display::addFlash(
1841
                Display::return_message(get_lang('Invalid start date was given.'), 'warning')
1842
            );
1843
1844
            return false;
1845
        } elseif (!empty($endDate) &&
1846
            !api_is_valid_date($endDate, 'Y-m-d H:i') &&
1847
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
1848
        ) {
1849
            Display::addFlash(
1850
                Display::return_message(get_lang('Invalid end date was given.'), 'warning')
1851
            );
1852
1853
            return false;
1854
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1855
            Display::addFlash(
1856
                Display::return_message(get_lang('The first date should be before the end date'), 'warning')
1857
            );
1858
1859
            return false;
1860
        } else {
1861
            $sessionInfo = self::get_session_by_name($name);
1862
            $exists = false;
1863
            if (!empty($sessionInfo) && (int) $sessionInfo['id'] !== $id) {
1864
                $exists = true;
1865
            }
1866
1867
            if ($exists) {
1868
                Display::addFlash(
1869
                    Display::return_message(get_lang('Session name already exists'), 'warning')
1870
                );
1871
1872
                return false;
1873
            } else {
1874
                $sessionEntity = api_get_session_entity($id);
1875
                $sessionEntity
1876
                    ->setTitle($name)
1877
                    ->setDuration($duration)
1878
                    ->setDescription($description)
1879
                    ->setShowDescription(1 === $showDescription)
1880
                    ->setVisibility($visibility)
1881
                    ->setSendSubscriptionNotification((bool) $sendSubscriptionNotification)
1882
                    ->setNotifyBoss((bool) $notifyBoss)
1883
                    ->setParentId($parentId)
1884
                    ->setDaysToReinscription((int) $daysBeforeFinishingForReinscription)
1885
                    ->setLastRepetition($lastRepetition)
1886
                    ->setDaysToNewRepetition((int) $daysBeforeFinishingToCreateNewRepetition)
1887
                    ->setValidityInDays((int) $validityInDays)
1888
                    ->setAccessStartDate(null)
1889
                    ->setAccessStartDate(null)
1890
                    ->setDisplayStartDate(null)
1891
                    ->setDisplayEndDate(null)
1892
                    ->setCoachAccessStartDate(null)
1893
                    ->setCoachAccessEndDate(null)
1894
                ;
1895
1896
                if ($parentId) {
1897
                    $sessionEntity->setParentId($parentId);
1898
                } else {
1899
                    $sessionEntity->setParentId(null);
1900
                }
1901
1902
                $sessionEntity->setDaysToReinscription($daysBeforeFinishingForReinscription);
1903
                $sessionEntity->setLastRepetition($lastRepetition);
1904
                $sessionEntity->setDaysToNewRepetition($daysBeforeFinishingToCreateNewRepetition);
1905
1906
                $newGeneralCoaches = array_map(
1907
                    fn($coachId) => api_get_user_entity($coachId),
1908
                    $coachesId
1909
                );
1910
                $currentGeneralCoaches = $sessionEntity->getGeneralCoaches();
1911
1912
                foreach ($newGeneralCoaches as $generalCoach) {
1913
                    if (!$sessionEntity->hasUserAsGeneralCoach($generalCoach)) {
1914
                        $sessionEntity->addGeneralCoach($generalCoach);
1915
                    }
1916
                }
1917
1918
                foreach ($currentGeneralCoaches as $generalCoach) {
1919
                    if (!in_array($generalCoach, $newGeneralCoaches, true)) {
1920
                        $sessionEntity->removeGeneralCoach($generalCoach);
1921
                    }
1922
                }
1923
1924
                if (!empty($sessionAdminId)) {
1925
                    $sessionEntity->addSessionAdmin(api_get_user_entity($sessionAdminId));
1926
                }
1927
1928
                if (!empty($startDate)) {
1929
                    $sessionEntity->setAccessStartDate(api_get_utc_datetime($startDate, true, true));
1930
                }
1931
1932
                if (!empty($endDate)) {
1933
                    $sessionEntity->setAccessEndDate(api_get_utc_datetime($endDate, true, true));
1934
                }
1935
1936
                if (!empty($displayStartDate)) {
1937
                    $sessionEntity->setDisplayStartDate(api_get_utc_datetime($displayStartDate, true, true));
1938
                }
1939
1940
                if (!empty($displayEndDate)) {
1941
                    $sessionEntity->setDisplayEndDate(api_get_utc_datetime($displayEndDate, true, true));
1942
                }
1943
1944
                if (!empty($coachStartDate)) {
1945
                    $sessionEntity->setCoachAccessStartDate(api_get_utc_datetime($coachStartDate, true, true));
1946
                }
1947
1948
                if (!empty($coachEndDate)) {
1949
                    $sessionEntity->setCoachAccessEndDate(api_get_utc_datetime($coachEndDate, true, true));
1950
                }
1951
1952
                if (!empty($sessionCategoryId)) {
1953
                    $category = $em->getRepository(SessionCategory::class)->find($sessionCategoryId);
1954
                    $sessionEntity->setCategory($category);
1955
                } else {
1956
                    $sessionEntity->setCategory(null);
1957
                }
1958
                $sessionEntity->setStatus($status);
1959
1960
                $em->flush();
1961
1962
                if (!empty($extraFields)) {
1963
                    $extraFields['item_id'] = $id;
1964
                    $sessionFieldValue = new ExtraFieldValue('session');
1965
                    $sessionFieldValue->saveFieldValues($extraFields);
1966
                }
1967
1968
                return $id;
1969
            }
1970
        }
1971
    }
1972
1973
    /**
1974
     * Delete session.
1975
     *
1976
     * @author Carlos Vargas  from existing code
1977
     *
1978
     * @param array $id_checked an array to delete sessions
1979
     * @param bool  $from_ws    optional, true if the function is called
1980
     *                          by a webservice, false otherwise
1981
     *
1982
     * @return bool
1983
     * */
1984
    public static function delete($id_checked, $from_ws = false)
1985
    {
1986
        $sessionId = null;
1987
        if (is_array($id_checked)) {
1988
            foreach ($id_checked as $sessionId) {
1989
                self::delete($sessionId);
1990
            }
1991
        } else {
1992
            $sessionId = (int) $id_checked;
1993
        }
1994
1995
        if (empty($sessionId)) {
1996
            return false;
1997
        }
1998
1999
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2000
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2001
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2002
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
2003
        $userGroupSessionTable = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
2004
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2005
        $trackAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
2006
2007
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
2008
        $em = Database::getManager();
2009
        $userId = api_get_user_id();
2010
        $user = api_get_user_entity();
2011
2012
        $repo = Container::getSequenceResourceRepository();
2013
        $sequenceResource = $repo->findRequirementForResource(
2014
            $sessionId,
2015
            SequenceResource::SESSION_TYPE
2016
        );
2017
2018
        $sessionEntity = api_get_session_entity($sessionId);
2019
        if (null === $sessionEntity) {
2020
            return false;
2021
        }
2022
2023
        if ($sequenceResource) {
2024
            Display::addFlash(
2025
                Display::return_message(
2026
                    get_lang('There is a sequence resource linked to this session. You must delete this link first.'),
2027
                    'error'
2028
                )
2029
            );
2030
2031
            return false;
2032
        }
2033
2034
        if (self::allowed($sessionEntity) && !$from_ws) {
2035
            if (!$sessionEntity->hasUserAsSessionAdmin($user) && !api_is_platform_admin()) {
2036
                api_not_allowed(true);
2037
            }
2038
        }
2039
2040
        // Delete Picture Session
2041
        SessionManager::deleteAsset($sessionId);
2042
2043
        // Delete documents inside a session
2044
        $courses = self::getCoursesInSession($sessionId);
2045
        foreach ($courses as $courseId) {
2046
            $courseInfo = api_get_course_info_by_id($courseId);
2047
            /*DocumentManager::deleteDocumentsFromSession($courseInfo, $sessionId);
2048
            $works = Database::select(
2049
                '*',
2050
                $tbl_student_publication,
2051
                [
2052
                    'where' => ['session_id = ? AND c_id = ?' => [$sessionId, $courseId]],
2053
                ]
2054
            );
2055
2056
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
2057
            foreach ($works as $index => $work) {
2058
                if ($work['filetype'] = 'folder') {
2059
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
2060
                }
2061
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
2062
            }*/
2063
        }
2064
2065
        $sessionName = $sessionEntity->getTitle();
2066
        $em->remove($sessionEntity);
2067
        $em->flush();
2068
2069
        // Class
2070
        $sql = "DELETE FROM $userGroupSessionTable
2071
                WHERE session_id = $sessionId";
2072
        Database::query($sql);
2073
2074
        //Database::query("DELETE FROM $tbl_student_publication WHERE session_id = $sessionId");
2075
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id = $sessionId");
2076
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id = $sessionId");
2077
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id = $sessionId");
2078
        //Database::query("DELETE FROM $tbl_item_properties WHERE session_id = $sessionId");
2079
        Database::query("DELETE FROM $tbl_url_session WHERE session_id = $sessionId");
2080
        Database::query("DELETE FROM $trackCourseAccess WHERE session_id = $sessionId");
2081
        Database::query("DELETE FROM $trackAccess WHERE session_id = $sessionId");
2082
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id = $sessionId";
2083
        Database::query($sql);
2084
2085
        $extraFieldValue = new ExtraFieldValue('session');
2086
        $extraFieldValue->deleteValuesByItem($sessionId);
2087
2088
        $repo->deleteSequenceResource($sessionId, SequenceResource::SESSION_TYPE);
2089
2090
        // Add event to system log
2091
        Event::addEvent(
2092
            LOG_SESSION_DELETE,
2093
            LOG_SESSION_ID,
2094
            $sessionName.' - id:'.$sessionId,
2095
            api_get_utc_datetime(),
2096
            $userId
2097
        );
2098
2099
        return true;
2100
    }
2101
2102
    /**
2103
     * @param int $id promotion id
2104
     *
2105
     * @return bool
2106
     */
2107
    public static function clear_session_ref_promotion($id)
2108
    {
2109
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2110
        $id = intval($id);
2111
        $sql = "UPDATE $tbl_session
2112
                SET promotion_id = 0
2113
                WHERE promotion_id = $id";
2114
        if (Database::query($sql)) {
2115
            return true;
2116
        } else {
2117
            return false;
2118
        }
2119
    }
2120
2121
    /**
2122
     * Subscribes students to the given session and optionally (default)
2123
     * unsubscribes previous users.
2124
     *
2125
     * @author Carlos Vargas from existing code
2126
     * @author Julio Montoya. Cleaning code.
2127
     *
2128
     * @param int   $sessionId
2129
     * @param array $userList
2130
     * @param int   $session_visibility
2131
     * @param bool  $empty_users
2132
     * @param bool  $registerUsersToAllCourses
2133
     *
2134
     * @return bool
2135
     */
2136
    public static function subscribeUsersToSession(
2137
        $sessionId,
2138
        $userList,
2139
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2140
        $empty_users = true,
2141
        $registerUsersToAllCourses = true
2142
    ) {
2143
        $sessionId = (int) $sessionId;
2144
2145
        if (empty($sessionId)) {
2146
            return false;
2147
        }
2148
2149
        foreach ($userList as $intUser) {
2150
            if ($intUser != strval(intval($intUser))) {
2151
                return false;
2152
            }
2153
        }
2154
2155
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2156
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2157
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2158
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2159
2160
        $session = api_get_session_entity($sessionId);
2161
2162
        // from function parameter
2163
        if (empty($session_visibility)) {
2164
            $session_visibility = $session->getVisibility();
2165
            //default status loaded if empty
2166
            // by default readonly 1
2167
            if (empty($session_visibility)) {
2168
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
2169
            }
2170
        } else {
2171
            if (!in_array($session_visibility, [SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE])) {
2172
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
2173
            }
2174
        }
2175
2176
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
2177
                WHERE session_id = $sessionId AND status = ".Session::STUDENT;
2178
        $result = Database::query($sql);
2179
        $existingUsers = [];
2180
        while ($row = Database::fetch_array($result)) {
2181
            $existingUsers[] = $row['user_id'];
2182
        }
2183
2184
        $sql = "SELECT c_id FROM $tbl_session_rel_course
2185
                WHERE session_id = $sessionId";
2186
        $result = Database::query($sql);
2187
        $course_list = [];
2188
        while ($row = Database::fetch_array($result)) {
2189
            $course_list[] = $row['c_id'];
2190
        }
2191
2192
        if ($session->getSendSubscriptionNotification() && is_array($userList)) {
2193
            foreach ($userList as $user_id) {
2194
                $tplSubject = new Template(
2195
                    null,
2196
                    false,
2197
                    false,
2198
                    false,
2199
                    false,
2200
                    false
2201
                );
2202
                $layoutSubject = $tplSubject->get_template(
2203
                    'mail/subject_subscription_to_session_confirmation.tpl'
2204
                );
2205
                $subject = $tplSubject->fetch($layoutSubject);
2206
                $user_info = api_get_user_info($user_id);
2207
2208
                $tplContent = new Template(
2209
                    null,
2210
                    false,
2211
                    false,
2212
                    false,
2213
                    false,
2214
                    false
2215
                );
2216
                // Variables for default template
2217
                $tplContent->assign('complete_name', stripslashes($user_info['complete_name']));
2218
                $tplContent->assign('session_name', $session->getTitle());
2219
                $tplContent->assign(
2220
                    'session_coaches',
2221
                    $session->getGeneralCoaches()->map(fn(User $coach) => UserManager::formatUserFullName($coach))
2222
                );
2223
                $layoutContent = $tplContent->get_template(
2224
                    'mail/content_subscription_to_session_confirmation.tpl'
2225
                );
2226
                $content = $tplContent->fetch($layoutContent);
2227
2228
                // Send email
2229
                api_mail_html(
2230
                    $user_info['complete_name'],
2231
                    $user_info['mail'],
2232
                    $subject,
2233
                    $content,
2234
                    api_get_person_name(
2235
                        api_get_setting('administratorName'),
2236
                        api_get_setting('administratorSurname')
2237
                    ),
2238
                    api_get_setting('emailAdministrator')
2239
                );
2240
2241
                // Record message in system
2242
                MessageManager::send_message_simple(
2243
                    $user_id,
2244
                    $subject,
2245
                    $content,
2246
                    api_get_user_id(),
2247
                    false,
2248
                    true
2249
                );
2250
            }
2251
        }
2252
2253
        if ($session->getNotifyBoss()) {
2254
            foreach ($userList as $user_id) {
2255
                $studentBossList = UserManager::getStudentBossList($user_id);
2256
2257
                if (!empty($studentBossList)) {
2258
                    $studentBossList = array_column($studentBossList, 'boss_id');
2259
                    foreach ($studentBossList as $bossId) {
2260
                        $boss = api_get_user_entity($bossId);
2261
                        self::notifyBossOfInscription($boss, $session, $user_id);
2262
                    }
2263
                }
2264
            }
2265
        }
2266
2267
        if ($registerUsersToAllCourses) {
2268
            foreach ($course_list as $courseId) {
2269
                // for each course in the session
2270
                $nbr_users = 0;
2271
                $courseId = (int) $courseId;
2272
2273
                $sql = "SELECT DISTINCT user_id
2274
                        FROM $tbl_session_rel_course_rel_user
2275
                        WHERE
2276
                            session_id = $sessionId AND
2277
                            c_id = $courseId AND
2278
                            status = ".Session::STUDENT;
2279
                $result = Database::query($sql);
2280
                $existingUsers = [];
2281
                while ($row = Database::fetch_array($result)) {
2282
                    $existingUsers[] = $row['user_id'];
2283
                }
2284
2285
                // Delete existing users
2286
                if ($empty_users) {
2287
                    foreach ($existingUsers as $existing_user) {
2288
                        if (!in_array($existing_user, $userList)) {
2289
                            self::unSubscribeUserFromCourseSession($existing_user, $courseId, $sessionId);
2290
                        }
2291
                    }
2292
                }
2293
2294
                $usersToSubscribeInCourse = array_filter(
2295
                    $userList,
2296
                    function ($userId) use ($existingUsers) {
2297
                        return !in_array($userId, $existingUsers);
2298
                    }
2299
                );
2300
2301
                self::insertUsersInCourse(
2302
                    $usersToSubscribeInCourse,
2303
                    $courseId,
2304
                    $sessionId,
2305
                    ['visibility' => $session_visibility],
2306
                    false
2307
                );
2308
            }
2309
        }
2310
2311
        // Delete users from the session
2312
        if (true === $empty_users) {
2313
            $sql = "DELETE FROM $tbl_session_rel_user
2314
                    WHERE
2315
                      session_id = $sessionId AND
2316
                      relation_type = ".Session::STUDENT;
2317
            // Don't reset session_rel_user.registered_at of users that will be registered later anyways.
2318
            if (!empty($userList)) {
2319
                $avoidDeleteThisUsers = " AND user_id NOT IN ('".implode("','", $userList)."')";
2320
                $sql .= $avoidDeleteThisUsers;
2321
            }
2322
            Event::addEvent(
2323
                LOG_SESSION_DELETE_USER,
2324
                LOG_USER_ID,
2325
                'all',
2326
                api_get_utc_datetime(),
2327
                api_get_user_id(),
2328
                null,
2329
                $sessionId
2330
            );
2331
            Database::query($sql);
2332
        }
2333
2334
        // Insert missing users into session
2335
        foreach ($userList as $enreg_user) {
2336
            $isUserSubscribed = self::isUserSubscribedAsStudent($sessionId, $enreg_user);
2337
            if (false === $isUserSubscribed) {
2338
                $enreg_user = (int) $enreg_user;
2339
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
2340
                        VALUES (".Session::STUDENT.", $sessionId, $enreg_user, '".api_get_utc_datetime()."')";
2341
                Database::query($sql);
2342
                Event::addEvent(
2343
                    LOG_SESSION_ADD_USER,
2344
                    LOG_USER_ID,
2345
                    $enreg_user,
2346
                    api_get_utc_datetime(),
2347
                    api_get_user_id(),
2348
                    null,
2349
                    $sessionId
2350
                );
2351
            }
2352
        }
2353
2354
        // update number of users in the session
2355
        $sql = "UPDATE $tbl_session
2356
                SET nbr_users = (SELECT count(user_id) FROM $tbl_session_rel_user WHERE session_id = $sessionId)
2357
                WHERE id = $sessionId";
2358
        Database::query($sql);
2359
2360
        return true;
2361
    }
2362
2363
    /**
2364
     * Sends a notification email to the student's boss when the student is enrolled in a session.
2365
     *
2366
     * @param User $boss The boss of the student to be notified.
2367
     * @param Session $session The session the student has been enrolled in.
2368
     * @param int $userId The ID of the student being enrolled.
2369
     */
2370
    public static function notifyBossOfInscription(User $boss, Session $session, int $userId): void
2371
    {
2372
        $tpl = Container::getTwig();
2373
2374
        $user_info = api_get_user_info($userId);
2375
2376
        $subject = $tpl->render(
2377
            '@ChamiloCore/Mailer/Legacy/subject_subscription_to_boss_notification.html.twig',
2378
            [
2379
                'locale' => $boss->getLocale(),
2380
                'boss_name' => $boss->getFullname(),
2381
                'student_name' => $user_info['complete_name'],
2382
                'session_name' => $session->getTitle(),
2383
            ]
2384
        );
2385
2386
        $content = $tpl->render(
2387
            '@ChamiloCore/Mailer/Legacy/content_subscription_to_boss_notification.html.twig',
2388
            [
2389
                'locale' => $boss->getLocale(),
2390
                'boss_name' => $boss->getFullname(),
2391
                'student_name' => $user_info['complete_name'],
2392
                'session_name' => $session->getTitle(),
2393
            ]
2394
        );
2395
2396
        // Send email
2397
        api_mail_html(
2398
            $boss->getFullname(),
2399
            $boss->getEmail(),
2400
            $subject,
2401
            $content,
2402
            api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname')),
2403
            api_get_setting('emailAdministrator')
2404
        );
2405
2406
        // Record message in system
2407
        MessageManager::send_message_simple(
2408
            $boss->getId(),
2409
            $subject,
2410
            $content,
2411
            api_get_user_id(),
2412
            false,
2413
            true
2414
        );
2415
    }
2416
2417
    /**
2418
     * Returns user list of the current users subscribed in the course-session.
2419
     *
2420
     * @param int   $sessionId
2421
     * @param array $courseInfo
2422
     * @param int   $status
2423
     *
2424
     * @return array
2425
     */
2426
    public static function getUsersByCourseSession(
2427
        $sessionId,
2428
        $courseInfo,
2429
        $status = null
2430
    ) {
2431
        $sessionId = (int) $sessionId;
2432
        $courseId = $courseInfo['real_id'];
2433
2434
        if (empty($sessionId) || empty($courseId)) {
2435
            return [];
2436
        }
2437
2438
        $statusCondition = null;
2439
        if (isset($status) && !is_null($status)) {
2440
            $status = (int) $status;
2441
            $statusCondition = " AND status = $status";
2442
        }
2443
2444
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2445
2446
        $sql = "SELECT DISTINCT user_id
2447
                FROM $table
2448
                WHERE
2449
                    session_id = $sessionId AND
2450
                    c_id = $courseId
2451
                    $statusCondition
2452
                ";
2453
2454
        $result = Database::query($sql);
2455
        $existingUsers = [];
2456
        while ($row = Database::fetch_array($result)) {
2457
            $existingUsers[] = $row['user_id'];
2458
        }
2459
2460
        return $existingUsers;
2461
    }
2462
2463
    /**
2464
     * Returns user list of the current users subscribed in the course-session.
2465
     *
2466
     * @param array $sessionList
2467
     * @param array $courseList
2468
     * @param int   $status
2469
     * @param int   $start
2470
     * @param int   $limit
2471
     *
2472
     * @return array
2473
     */
2474
    public static function getUsersByCourseAndSessionList(
2475
        $sessionList,
2476
        $courseList,
2477
        $status = null,
2478
        $start = null,
2479
        $limit = null
2480
    ) {
2481
        if (empty($sessionList) || empty($courseList)) {
2482
            return [];
2483
        }
2484
        $sessionListToString = implode("','", $sessionList);
2485
        $courseListToString = implode("','", $courseList);
2486
2487
        $statusCondition = null;
2488
        if (isset($status) && !is_null($status)) {
2489
            $status = (int) $status;
2490
            $statusCondition = " AND status = $status";
2491
        }
2492
2493
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2494
2495
        $sql = "SELECT DISTINCT user_id
2496
                FROM $table
2497
                WHERE
2498
                    session_id IN ('$sessionListToString') AND
2499
                    c_id IN ('$courseListToString')
2500
                    $statusCondition
2501
                ";
2502
        if (!is_null($start) && !is_null($limit)) {
2503
            $start = (int) $start;
2504
            $limit = (int) $limit;
2505
            $sql .= "LIMIT $start, $limit";
2506
        }
2507
        $result = Database::query($sql);
2508
        $existingUsers = [];
2509
        while ($row = Database::fetch_array($result)) {
2510
            $existingUsers[] = $row['user_id'];
2511
        }
2512
2513
        return $existingUsers;
2514
    }
2515
2516
    /**
2517
     * Remove a list of users from a course-session.
2518
     *
2519
     * @param array $userList
2520
     * @param int   $sessionId
2521
     * @param array $courseInfo
2522
     * @param int   $status
2523
     * @param bool  $updateTotal
2524
     *
2525
     * @return bool
2526
     */
2527
    public static function removeUsersFromCourseSession(
2528
        $userList,
2529
        $sessionId,
2530
        $courseInfo,
2531
        $status = null,
2532
        $updateTotal = true
2533
    ) {
2534
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2535
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2536
        $sessionId = (int) $sessionId;
2537
2538
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
2539
            return false;
2540
        }
2541
2542
        $courseId = is_array($courseInfo) ? $courseInfo['real_id'] : $courseInfo;
2543
2544
        $statusCondition = null;
2545
        if (isset($status) && !is_null($status)) {
2546
            $status = (int) $status;
2547
            $statusCondition = " AND status = $status";
2548
        }
2549
2550
        foreach ($userList as $userId) {
2551
            $userId = (int) $userId;
2552
            $sql = "DELETE FROM $table
2553
                    WHERE
2554
                        session_id = $sessionId AND
2555
                        c_id = $courseId AND
2556
                        user_id = $userId
2557
                        $statusCondition
2558
                    ";
2559
            Database::query($sql);
2560
2561
            Event::addEvent(
2562
                LOG_SESSION_DELETE_USER_COURSE,
2563
                LOG_USER_ID,
2564
                $userId,
2565
                api_get_utc_datetime(),
2566
                api_get_user_id(),
2567
                $courseId,
2568
                $sessionId
2569
            );
2570
        }
2571
2572
        if ($updateTotal) {
2573
            // Count users in this session-course relation
2574
            $sql = "SELECT COUNT(user_id) as nbUsers
2575
                    FROM $table
2576
                    WHERE
2577
                        session_id = $sessionId AND
2578
                        c_id = $courseId AND
2579
                        status = ".Session::STUDENT;
2580
            $result = Database::query($sql);
2581
            [$userCount] = Database::fetch_array($result);
2582
2583
            // update the session-course relation to add the users total
2584
            $sql = "UPDATE $tableSessionCourse
2585
                    SET nbr_users = $userCount
2586
                    WHERE
2587
                        session_id = $sessionId AND
2588
                        c_id = $courseId";
2589
            Database::query($sql);
2590
        }
2591
    }
2592
2593
    /**
2594
     * Subscribe a user to an specific course inside a session.
2595
     *
2596
     * @param array  $user_list
2597
     * @param int    $session_id
2598
     * @param string $course_code
2599
     * @param int    $session_visibility
2600
     * @param bool   $removeUsersNotInList
2601
     *
2602
     * @return bool
2603
     */
2604
    public static function subscribe_users_to_session_course(
2605
        $user_list,
2606
        $session_id,
2607
        $course_code,
2608
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2609
        $removeUsersNotInList = false
2610
    ) {
2611
        if (empty($session_id) || empty($course_code)) {
2612
            return false;
2613
        }
2614
2615
        $session_id = (int) $session_id;
2616
        $session_visibility = (int) $session_visibility;
2617
        $course_code = Database::escape_string($course_code);
2618
        $courseInfo = api_get_course_info($course_code);
2619
        $courseId = $courseInfo['real_id'];
2620
        $subscribe = (int) api_get_course_setting('subscribe_users_to_forum_notifications', $courseInfo);
2621
        $forums = [];
2622
        if (1 === $subscribe) {
2623
            $forums = get_forums($courseId, $session_id);
2624
        }
2625
2626
        if ($removeUsersNotInList) {
2627
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2628
2629
            if (!empty($user_list)) {
2630
                $userToDelete = array_diff($currentUsers, $user_list);
2631
            } else {
2632
                $userToDelete = $currentUsers;
2633
            }
2634
2635
            if (!empty($userToDelete)) {
2636
                self::removeUsersFromCourseSession(
2637
                    $userToDelete,
2638
                    $session_id,
2639
                    $courseInfo,
2640
                    0,
2641
                    true
2642
                );
2643
            }
2644
        }
2645
2646
        self::insertUsersInCourse(
2647
            $user_list,
2648
            $courseId,
2649
            $session_id,
2650
            ['visibility' => $session_visibility],
2651
            true,
2652
            true
2653
        );
2654
    }
2655
2656
    /**
2657
     * Unsubscribe user from session.
2658
     *
2659
     * @param int Session id
2660
     * @param int User id
2661
     *
2662
     * @return bool True in case of success, false in case of error
2663
     */
2664
    public static function unsubscribe_user_from_session($session_id, $user_id)
2665
    {
2666
        $session_id = (int) $session_id;
2667
        $user_id = (int) $user_id;
2668
2669
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2670
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2671
2672
        $sql = "DELETE FROM $tbl_session_rel_user
2673
                WHERE
2674
                    session_id = $session_id AND
2675
                    user_id = $user_id ";
2676
        Database::query($sql);
2677
2678
        // Update number of users
2679
        $sql = "UPDATE $tbl_session
2680
                SET nbr_users = nbr_users - 1
2681
                WHERE id = $session_id ";
2682
        Database::query($sql);
2683
2684
        Event::addEvent(
2685
            LOG_SESSION_DELETE_USER,
2686
            LOG_USER_ID,
2687
            $user_id,
2688
            api_get_utc_datetime(),
2689
            api_get_user_id(),
2690
            null,
2691
            $session_id
2692
        );
2693
2694
        // Get the list of courses related to this session
2695
        $course_list = self::get_course_list_by_session_id($session_id);
2696
        if (!empty($course_list)) {
2697
            foreach ($course_list as $course) {
2698
                self::unSubscribeUserFromCourseSession($user_id, $course['id'], $session_id);
2699
            }
2700
        }
2701
2702
        return true;
2703
    }
2704
2705
    /**
2706
     * @param int $user_id
2707
     * @param int $courseId
2708
     * @param int $session_id
2709
     */
2710
    public static function unSubscribeUserFromCourseSession($user_id, $courseId, $session_id)
2711
    {
2712
        $user_id = (int) $user_id;
2713
        $courseId = (int) $courseId;
2714
        $session_id = (int) $session_id;
2715
2716
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2717
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2718
2719
        // Delete user from course
2720
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2721
                WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2722
        $result = Database::query($sql);
2723
2724
        if (Database::affected_rows($result)) {
2725
            // Update number of users in this relation
2726
            $sql = "UPDATE $tbl_session_rel_course SET
2727
                    nbr_users = nbr_users - 1
2728
                    WHERE session_id = $session_id AND c_id = $courseId";
2729
            Database::query($sql);
2730
        }
2731
2732
        Event::addEvent(
2733
            LOG_SESSION_DELETE_USER_COURSE,
2734
            LOG_USER_ID,
2735
            $user_id,
2736
            api_get_utc_datetime(),
2737
            api_get_user_id(),
2738
            $courseId,
2739
            $session_id
2740
        );
2741
    }
2742
2743
    /**
2744
     * Subscribes courses to the given session and optionally (default)
2745
     * unsubscribe previous users.
2746
     *
2747
     * @author Carlos Vargas from existing code
2748
     *
2749
     * @param int   $sessionId
2750
     * @param array $courseList                     List of courses int ids
2751
     * @param bool  $removeExistingCoursesWithUsers Whether to unsubscribe
2752
     *                                              existing courses and users (true, default) or not (false)
2753
     * @param bool  $copyEvaluation                 from base course to session course
2754
     * @param bool  $copyCourseTeachersAsCoach
2755
     * @param bool  $importAssignments
2756
     *
2757
     * @throws Exception
2758
     *
2759
     * @return bool False on failure, true otherwise
2760
     * */
2761
    public static function add_courses_to_session(
2762
        $sessionId,
2763
        $courseList,
2764
        $removeExistingCoursesWithUsers = true,
2765
        $copyEvaluation = false,
2766
        $copyCourseTeachersAsCoach = false,
2767
        $importAssignments = false
2768
    ) {
2769
        $sessionId = (int) $sessionId;
2770
2771
        if (empty($sessionId) || empty($courseList)) {
2772
            return false;
2773
        }
2774
2775
        $session = api_get_session_entity($sessionId);
2776
2777
        if (!$session) {
2778
            return false;
2779
        }
2780
        $sessionVisibility = $session->getVisibility();
2781
2782
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2783
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2784
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2785
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2786
2787
        // Get list of courses subscribed to this session
2788
        $sql = "SELECT c_id
2789
                FROM $tbl_session_rel_course
2790
                WHERE session_id = $sessionId";
2791
        $rs = Database::query($sql);
2792
        $existingCourses = Database::store_result($rs);
2793
        $nbr_courses = count($existingCourses);
2794
2795
        // Get list of users subscribed to this session
2796
        $sql = "SELECT user_id
2797
                FROM $tbl_session_rel_user
2798
                WHERE
2799
                    session_id = $sessionId AND
2800
                    relation_type = ".Session::STUDENT;
2801
        $result = Database::query($sql);
2802
        $user_list = Database::store_result($result);
2803
2804
        // Remove existing courses from the session.
2805
        if (true === $removeExistingCoursesWithUsers && !empty($existingCourses)) {
2806
            foreach ($existingCourses as $existingCourse) {
2807
                if (!in_array($existingCourse['c_id'], $courseList)) {
2808
                    $sql = "DELETE FROM $tbl_session_rel_course
2809
                            WHERE
2810
                                c_id = ".$existingCourse['c_id']." AND
2811
                                session_id = $sessionId";
2812
                    Database::query($sql);
2813
2814
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2815
                            WHERE
2816
                                c_id = ".$existingCourse['c_id']." AND
2817
                                session_id = $sessionId";
2818
                    Database::query($sql);
2819
2820
                    Event::addEvent(
2821
                        LOG_SESSION_DELETE_COURSE,
2822
                        LOG_COURSE_ID,
2823
                        $existingCourse['c_id'],
2824
                        api_get_utc_datetime(),
2825
                        api_get_user_id(),
2826
                        $existingCourse['c_id'],
2827
                        $sessionId
2828
                    );
2829
2830
                    CourseManager::remove_course_ranking(
2831
                        $existingCourse['c_id'],
2832
                        $sessionId
2833
                    );
2834
                    $nbr_courses--;
2835
                }
2836
            }
2837
        }
2838
2839
        // Pass through the courses list we want to add to the session
2840
        foreach ($courseList as $courseId) {
2841
            $courseInfo = api_get_course_info_by_id($courseId);
2842
2843
            // If course doesn't exist continue!
2844
            if (empty($courseInfo)) {
2845
                continue;
2846
            }
2847
2848
            $exists = false;
2849
            // check if the course we want to add is already subscribed
2850
            foreach ($existingCourses as $existingCourse) {
2851
                if ($courseId == $existingCourse['c_id']) {
2852
                    $exists = true;
2853
                }
2854
            }
2855
2856
            if (!$exists) {
2857
                // Copy gradebook categories and links (from base course)
2858
                // to the new course session
2859
                if ($copyEvaluation) {
2860
                    $cats = Category::load(null, null, $courseId);
2861
                    if (!empty($cats)) {
2862
                        $sessionCategory = Category:: load(
2863
                            null,
2864
                            null,
2865
                            $courseId,
2866
                            null,
2867
                            null,
2868
                            $sessionId,
2869
                            null
2870
                        );
2871
2872
                        // @todo remove commented code
2873
                        if (empty($sessionCategory)) {
2874
                            // There is no category for this course+session, so create one
2875
                            $cat = new Category();
2876
                            $sessionName = $session->getTitle();
2877
                            $cat->set_name($courseInfo['code'].' - '.get_lang('Session').' '.$sessionName);
2878
                            $cat->set_session_id($sessionId);
2879
                            $cat->setCourseId($courseId);
2880
                            $cat->set_description(null);
2881
                            //$cat->set_user_id($stud_id);
2882
                            $cat->set_parent_id(0);
2883
                            $cat->set_weight(100);
2884
                            $cat->set_visible(0);
2885
                            $cat->set_certificate_min_score(75);
2886
                            $cat->setGenerateCertificates(1);
2887
                            $cat->setIsRequirement(1);
2888
                            $cat->add();
2889
                            $sessionGradeBookCategoryId = $cat->get_id();
2890
                        } else {
2891
                            if (!empty($sessionCategory[0])) {
2892
                                $sessionGradeBookCategoryId = $sessionCategory[0]->get_id();
2893
                            }
2894
                        }
2895
2896
                        $categoryIdList = [];
2897
                        /** @var Category $cat */
2898
                        foreach ($cats as $cat) {
2899
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2900
                        }
2901
2902
                        $newCategoryIdList = [];
2903
                        foreach ($cats as $cat) {
2904
                            $links = $cat->get_links(
2905
                                null,
2906
                                false,
2907
                                $courseId,
2908
                                $sessionId
2909
                            );
2910
2911
                            //$cat->set_session_id($sessionId);
2912
                            //$oldCategoryId = $cat->get_id();
2913
                            //$newId = $cat->add();
2914
                            //$newCategoryIdList[$oldCategoryId] = $newId;
2915
                            //$parentId = $cat->get_parent_id();
2916
2917
                            /*if (!empty($parentId)) {
2918
                                $newParentId = $newCategoryIdList[$parentId];
2919
                                $cat->set_parent_id($newParentId);
2920
                                $cat->save();
2921
                            }*/
2922
2923
                            if (!empty($links)) {
2924
                                /** @var AbstractLink $link */
2925
                                foreach ($links as $link) {
2926
                                    //$newCategoryId = $newCategoryIdList[$link->get_category_id()];
2927
                                    $link->set_category_id($sessionGradeBookCategoryId);
2928
                                    $link->add();
2929
                                }
2930
                            }
2931
2932
                            $evaluationList = $cat->get_evaluations(
2933
                                null,
2934
                                false,
2935
                                $courseId,
2936
                                $sessionId
2937
                            );
2938
2939
                            if (!empty($evaluationList)) {
2940
                                /** @var Evaluation $evaluation */
2941
                                foreach ($evaluationList as $evaluation) {
2942
                                    //$evaluationId = $newCategoryIdList[$evaluation->get_category_id()];
2943
                                    $evaluation->set_category_id($sessionGradeBookCategoryId);
2944
                                    $evaluation->add();
2945
                                }
2946
                            }
2947
                        }
2948
2949
                        // Create
2950
                        DocumentManager::generateDefaultCertificate(
2951
                            $courseInfo,
2952
                            true,
2953
                            $sessionId
2954
                        );
2955
                    }
2956
                }
2957
2958
                if ($importAssignments) {
2959
                    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2960
                    $sql = " SELECT * FROM $workTable
2961
                             WHERE active = 1 AND
2962
                                   c_id = $courseId AND
2963
                                   parent_id = 0 AND
2964
                                   (session_id IS NULL OR session_id = 0)";
2965
                    $result = Database::query($sql);
2966
                    $workList = Database::store_result($result, 'ASSOC');
2967
2968
                    foreach ($workList as $work) {
2969
                        $values = [
2970
                            'work_title' => $work['title'],
2971
                            'new_dir' => $work['url'].'_session_'.$sessionId,
2972
                            'description' => $work['description'],
2973
                            'qualification' => $work['qualification'],
2974
                            'allow_text_assignment' => $work['allow_text_assignment'],
2975
                        ];
2976
                        // @todo add addDir with resources
2977
                        /*addDir(
2978
                            $values,
2979
                            api_get_user_id(),
2980
                            $courseInfo,
2981
                            0,
2982
                            $sessionId
2983
                        );*/
2984
                    }
2985
                }
2986
                // If the course isn't subscribed yet
2987
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2988
                        VALUES ($sessionId, $courseId, 0, 0)";
2989
                Database::query($sql);
2990
2991
                Event::addEvent(
2992
                    LOG_SESSION_ADD_COURSE,
2993
                    LOG_COURSE_ID,
2994
                    $courseId,
2995
                    api_get_utc_datetime(),
2996
                    api_get_user_id(),
2997
                    $courseId,
2998
                    $sessionId
2999
                );
3000
3001
                // We add the current course in the existing courses array,
3002
                // to avoid adding another time the current course
3003
                $existingCourses[] = ['c_id' => $courseId];
3004
                $nbr_courses++;
3005
3006
                // Subscribe all the users from the session to this course inside the session
3007
                self::insertUsersInCourse(
3008
                    array_column($user_list, 'user_id'),
3009
                    $courseId,
3010
                    $sessionId,
3011
                    ['visibility' => $sessionVisibility],
3012
                    false
3013
                );
3014
            }
3015
3016
            if ($copyCourseTeachersAsCoach) {
3017
                $teachers = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
3018
                if (!empty($teachers)) {
3019
                    foreach ($teachers as $teacher) {
3020
                        self::updateCoaches(
3021
                            $sessionId,
3022
                            $courseId,
3023
                            [$teacher['user_id']],
3024
                            false
3025
                        );
3026
                    }
3027
                }
3028
            }
3029
        }
3030
3031
        $sql = "UPDATE $tbl_session SET nbr_courses = $nbr_courses WHERE id = $sessionId";
3032
        Database::query($sql);
3033
3034
        return true;
3035
    }
3036
3037
    /**
3038
     * Unsubscribe course from a session.
3039
     *
3040
     * @param int $session_id
3041
     * @param int $course_id
3042
     *
3043
     * @return bool True in case of success, false otherwise
3044
     */
3045
    public static function unsubscribe_course_from_session($session_id, $course_id)
3046
    {
3047
        $session_id = (int) $session_id;
3048
        $course_id = (int) $course_id;
3049
3050
        if (empty($course_id) || empty($session_id)) {
3051
            return false;
3052
        }
3053
3054
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3055
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3056
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3057
3058
        // Unsubscribe course.
3059
        $sql = "DELETE FROM $tbl_session_rel_course
3060
                WHERE c_id = $course_id AND session_id = $session_id";
3061
        $result = Database::query($sql);
3062
        $nb_affected = Database::affected_rows($result);
3063
3064
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
3065
                WHERE c_id = $course_id AND session_id = $session_id";
3066
        Database::query($sql);
3067
3068
        Event::addEvent(
3069
            LOG_SESSION_DELETE_COURSE,
3070
            LOG_COURSE_ID,
3071
            $course_id,
3072
            api_get_utc_datetime(),
3073
            api_get_user_id(),
3074
            $course_id,
3075
            $session_id
3076
        );
3077
3078
        if ($nb_affected > 0) {
3079
            // Update number of courses in the session
3080
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
3081
                    WHERE id = $session_id";
3082
            Database::query($sql);
3083
3084
            return true;
3085
        }
3086
3087
        return false;
3088
    }
3089
3090
    /**
3091
     * Creates a new extra field for a given session.
3092
     *
3093
     * @param string $variable    Field's internal variable name
3094
     * @param int    $fieldType   Field's type
3095
     * @param string $displayText Field's language var name
3096
     * @param string $default     Field's default value
3097
     *
3098
     * @return int new extra field id
3099
     */
3100
    public static function create_session_extra_field(
3101
        $variable,
3102
        $valueType,
3103
        $displayText,
3104
        $default = ''
3105
    ) {
3106
        $extraField = new ExtraFieldModel('session');
3107
        $params = [
3108
            'variable' => $variable,
3109
            'value_type' => $valueType,
3110
            'display_text' => $displayText,
3111
            'default_value' => $default,
3112
        ];
3113
3114
        return $extraField->save($params);
3115
    }
3116
3117
    /**
3118
     * Update an extra field value for a given session.
3119
     *
3120
     * @param int    $sessionId Session ID
3121
     * @param string $variable  Field variable name
3122
     * @param string $value     Optional. Default field value
3123
     *
3124
     * @return bool|int An integer when register a new extra field. And boolean when update the extrafield
3125
     */
3126
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
3127
    {
3128
        $extraFieldValue = new ExtraFieldValue('session');
3129
        $params = [
3130
            'item_id' => $sessionId,
3131
            'variable' => $variable,
3132
            'value' => $value,
3133
        ];
3134
3135
        return $extraFieldValue->save($params);
3136
    }
3137
3138
    /**
3139
     * Checks the relationship between a session and a course.
3140
     *
3141
     * @param int $session_id
3142
     * @param int $courseId
3143
     *
3144
     * @return bool returns TRUE if the session and the course are related, FALSE otherwise
3145
     * */
3146
    public static function relation_session_course_exist($session_id, $courseId)
3147
    {
3148
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3149
        $return_value = false;
3150
        $sql = "SELECT c_id FROM $tbl_session_course
3151
                WHERE
3152
                  session_id = ".intval($session_id)." AND
3153
                  c_id = ".intval($courseId);
3154
        $result = Database::query($sql);
3155
        $num = Database::num_rows($result);
3156
        if ($num > 0) {
3157
            $return_value = true;
3158
        }
3159
3160
        return $return_value;
3161
    }
3162
3163
    /**
3164
     * Get the session information by name.
3165
     *
3166
     * @param string $name
3167
     *
3168
     * @return mixed false if the session does not exist, array if the session exist
3169
     */
3170
    public static function get_session_by_name($name)
3171
    {
3172
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3173
        $name = Database::escape_string(trim($name));
3174
        if (empty($name)) {
3175
            return false;
3176
        }
3177
3178
        $sql = 'SELECT *
3179
		        FROM '.$tbl_session.'
3180
		        WHERE title = "'.$name.'"';
3181
        $result = Database::query($sql);
3182
        $num = Database::num_rows($result);
3183
        if ($num > 0) {
3184
            return Database::fetch_array($result);
3185
        } else {
3186
            return false;
3187
        }
3188
    }
3189
3190
    /**
3191
     * @param int $sessionId
3192
     * @param int $name
3193
     *
3194
     * @return bool
3195
     */
3196
    public static function sessionNameExistBesidesMySession($sessionId, $name)
3197
    {
3198
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
3199
        $name = Database::escape_string(trim($name));
3200
        $sessionId = (int) $sessionId;
3201
3202
        if (empty($name)) {
3203
            return false;
3204
        }
3205
3206
        $sql = "SELECT *
3207
		        FROM $table
3208
		        WHERE title = '$name' AND id <> $sessionId ";
3209
        $result = Database::query($sql);
3210
        $num = Database::num_rows($result);
3211
        if ($num > 0) {
3212
            return true;
3213
        }
3214
3215
        return false;
3216
    }
3217
3218
    /**
3219
     * Create a session category.
3220
     *
3221
     * @author Jhon Hinojosa <[email protected]>, from existing code
3222
     *
3223
     * @param string        name
3224
     * @param int        year_start
3225
     * @param int        month_start
3226
     * @param int        day_start
3227
     * @param int        year_end
3228
     * @param int        month_end
3229
     * @param int        day_end
3230
     *
3231
     * @return int session ID
3232
     * */
3233
    public static function create_category_session(
3234
        $sname,
3235
        $syear_start,
3236
        $smonth_start,
3237
        $sday_start,
3238
        $syear_end,
3239
        $smonth_end,
3240
        $sday_end
3241
    ) {
3242
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3243
        $name = html_filter(trim($sname));
3244
        $year_start = intval($syear_start);
3245
        $month_start = intval($smonth_start);
3246
        $day_start = intval($sday_start);
3247
        $year_end = intval($syear_end);
3248
        $month_end = intval($smonth_end);
3249
        $day_end = intval($sday_end);
3250
3251
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3252
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3253
3254
        if (empty($name)) {
3255
            $msg = get_lang('Please give a name to the sessions category');
3256
3257
            return $msg;
3258
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3259
            $msg = get_lang('Invalid start date was given.');
3260
3261
            return $msg;
3262
        } elseif (!$month_end && !$day_end && !$year_end) {
3263
            $date_end = '';
3264
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3265
            $msg = get_lang('Invalid end date was given.');
3266
3267
            return $msg;
3268
        } elseif ($date_start >= $date_end) {
3269
            $msg = get_lang('The first date should be before the end date');
3270
3271
            return $msg;
3272
        }
3273
3274
        $access_url_id = api_get_current_access_url_id();
3275
        $params = [
3276
            'title' => $name,
3277
            'date_start' => $date_start,
3278
            'access_url_id' => $access_url_id,
3279
        ];
3280
3281
        if (!empty($date_end)) {
3282
            $params['date_end'] = $date_end;
3283
        }
3284
3285
        $id = Database::insert($tbl_session_category, $params);
3286
3287
        // Add event to system log
3288
        $user_id = api_get_user_id();
3289
        Event::addEvent(
3290
            LOG_SESSION_CATEGORY_CREATE,
3291
            LOG_SESSION_CATEGORY_ID,
3292
            $id,
3293
            api_get_utc_datetime(),
3294
            $user_id
3295
        );
3296
3297
        return $id;
3298
    }
3299
3300
    /**
3301
     * Edit a sessions category.
3302
     *
3303
     * @author Jhon Hinojosa <[email protected]>,from existing code
3304
     *
3305
     * @param int        id
3306
     * @param string        name
3307
     * @param int        year_start
3308
     * @param int        month_start
3309
     * @param int        day_start
3310
     * @param int        year_end
3311
     * @param int        month_end
3312
     * @param int        day_end
3313
     *
3314
     * @return bool
3315
     *              The parameter id is a primary key
3316
     * */
3317
    public static function edit_category_session(
3318
        $id,
3319
        $sname,
3320
        $syear_start,
3321
        $smonth_start,
3322
        $sday_start,
3323
        $syear_end,
3324
        $smonth_end,
3325
        $sday_end
3326
    ) {
3327
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3328
        $name = html_filter(trim($sname));
3329
        $year_start = intval($syear_start);
3330
        $month_start = intval($smonth_start);
3331
        $day_start = intval($sday_start);
3332
        $year_end = intval($syear_end);
3333
        $month_end = intval($smonth_end);
3334
        $day_end = intval($sday_end);
3335
        $id = intval($id);
3336
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3337
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3338
3339
        if (empty($name)) {
3340
            $msg = get_lang('Please give a name to the sessions category');
3341
3342
            return $msg;
3343
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3344
            $msg = get_lang('Invalid start date was given.');
3345
3346
            return $msg;
3347
        } elseif (!$month_end && !$day_end && !$year_end) {
3348
            $date_end = null;
3349
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3350
            $msg = get_lang('Invalid end date was given.');
3351
3352
            return $msg;
3353
        } elseif ($date_start >= $date_end) {
3354
            $msg = get_lang('The first date should be before the end date');
3355
3356
            return $msg;
3357
        }
3358
        if (null != $date_end) {
3359
            $sql = "UPDATE $tbl_session_category
3360
                    SET
3361
                        title = '".Database::escape_string($name)."',
3362
                        date_start = '$date_start' ,
3363
                        date_end = '$date_end'
3364
                    WHERE id= $id";
3365
        } else {
3366
            $sql = "UPDATE $tbl_session_category SET
3367
                        title = '".Database::escape_string($name)."',
3368
                        date_start = '$date_start',
3369
                        date_end = NULL
3370
                    WHERE id= $id";
3371
        }
3372
        $result = Database::query($sql);
3373
3374
        return $result ? true : false;
3375
    }
3376
3377
    /**
3378
     * Delete sessions categories.
3379
     *
3380
     * @param array|int $categoryId
3381
     * @param bool      $deleteSessions Optional. Include delete session.
3382
     * @param bool      $fromWs         Optional. True if the function is called by a webservice, false otherwise.
3383
     *
3384
     * @return bool Nothing, or false on error
3385
     *              The parameters is a array to delete sessions
3386
     *
3387
     * @author Jhon Hinojosa <[email protected]>, from existing code
3388
     */
3389
    public static function delete_session_category($categoryId, $deleteSessions = false, $fromWs = false)
3390
    {
3391
        $tblSessionCategory = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3392
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
3393
3394
        if (is_array($categoryId)) {
3395
            $categoryId = array_map('intval', $categoryId);
3396
        } else {
3397
            $categoryId = [(int) $categoryId];
3398
        }
3399
3400
        $categoryId = implode(', ', $categoryId);
3401
3402
        if ($deleteSessions) {
3403
            $sql = "SELECT id FROM $tblSession WHERE session_category_id IN ($categoryId)";
3404
            $result = Database::query($sql);
3405
            while ($rows = Database::fetch_array($result)) {
3406
                $sessionId = $rows['id'];
3407
                self::delete($sessionId, $fromWs);
3408
            }
3409
        } else {
3410
            $sql = "UPDATE $tblSession SET session_category_id = NULL WHERE session_category_id IN ($categoryId)";
3411
            Database::query($sql);
3412
        }
3413
3414
        $sql = "DELETE FROM $tblSessionCategory WHERE id IN ($categoryId)";
3415
        Database::query($sql);
3416
3417
        // Add event to system log
3418
        Event::addEvent(
3419
            LOG_SESSION_CATEGORY_DELETE,
3420
            LOG_SESSION_CATEGORY_ID,
3421
            $categoryId,
3422
            api_get_utc_datetime(),
3423
            api_get_user_id()
3424
        );
3425
3426
        return true;
3427
    }
3428
3429
    /**
3430
     * Get a list of sessions of which the given conditions match with an = 'cond'.
3431
     *
3432
     * @param array $conditions          a list of condition example :
3433
     *                                   array('status' => STUDENT) or
3434
     *                                   array('s.title' => array('operator' => 'LIKE', value = '%$needle%'))
3435
     * @param array $order_by            a list of fields on which sort
3436
     * @param int   $urlId
3437
     * @param array $onlyThisSessionList
3438
     *
3439
     * @return array an array with all sessions of the platform
3440
     *
3441
     * @todo   optional course code parameter, optional sorting parameters...
3442
     */
3443
    public static function get_sessions_list(
3444
        $conditions = [],
3445
        $order_by = [],
3446
        $from = null,
3447
        $to = null,
3448
        $urlId = 0,
3449
        $onlyThisSessionList = []
3450
    ) {
3451
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3452
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3453
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
3454
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3455
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3456
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
3457
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
3458
        $return_array = [];
3459
3460
        $sql_query = " SELECT
3461
                    DISTINCT(s.id),
3462
                    s.title,
3463
                    s.nbr_courses,
3464
                    s.access_start_date,
3465
                    s.access_end_date,
3466
                    sc.title as category_name,
3467
                    s.promotion_id
3468
				FROM $session_table s
3469
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
3470
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
3471
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
3472
				INNER JOIN $course_table c ON sco.c_id = c.id
3473
				WHERE ar.access_url_id = $urlId ";
3474
3475
        $availableFields = [
3476
            's.id',
3477
            's.title',
3478
            'c.id',
3479
        ];
3480
3481
        $availableOperator = [
3482
            'like',
3483
            '>=',
3484
            '<=',
3485
            '=',
3486
        ];
3487
3488
        if (count($conditions) > 0) {
3489
            foreach ($conditions as $field => $options) {
3490
                $operator = strtolower($options['operator']);
3491
                $value = Database::escape_string($options['value']);
3492
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
3493
                    $sql_query .= ' AND '.$field." $operator '".$value."'";
3494
                }
3495
            }
3496
        }
3497
3498
        if (!empty($onlyThisSessionList)) {
3499
            $onlyThisSessionList = array_map('intval', $onlyThisSessionList);
3500
            $onlyThisSessionList = implode("','", $onlyThisSessionList);
3501
            $sql_query .= " AND s.id IN ('$onlyThisSessionList') ";
3502
        }
3503
3504
        $orderAvailableList = ['title'];
3505
        if (count($order_by) > 0) {
3506
            $order = null;
3507
            $direction = null;
3508
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
3509
                $order = $order_by[0];
3510
            }
3511
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), ['desc', 'asc'])) {
3512
                $direction = $order_by[1];
3513
            }
3514
3515
            if (!empty($order)) {
3516
                $sql_query .= " ORDER BY $order $direction ";
3517
            }
3518
        }
3519
3520
        if (!is_null($from) && !is_null($to)) {
3521
            $to = (int) $to;
3522
            $from = (int) $from;
3523
            $sql_query .= "LIMIT $from, $to";
3524
        }
3525
3526
        $sql_result = Database::query($sql_query);
3527
        if (Database::num_rows($sql_result) > 0) {
3528
            while ($result = Database::fetch_array($sql_result)) {
3529
                $return_array[$result['id']] = $result;
3530
            }
3531
        }
3532
3533
        return $return_array;
3534
    }
3535
3536
    /**
3537
     * Get the session category information by id.
3538
     *
3539
     * @param string session category ID
3540
     *
3541
     * @return mixed false if the session category does not exist, array if the session category exists
3542
     */
3543
    public static function get_session_category($id)
3544
    {
3545
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3546
        $id = (int) $id;
3547
        $sql = "SELECT id, title, date_start, date_end
3548
                FROM $table
3549
                WHERE id= $id";
3550
        $result = Database::query($sql);
3551
        $num = Database::num_rows($result);
3552
        if ($num > 0) {
3553
            return Database::fetch_array($result);
3554
        } else {
3555
            return false;
3556
        }
3557
    }
3558
3559
    /**
3560
     * Get Hot Sessions (limit 8).
3561
     *
3562
     * @return array with sessions
3563
     */
3564
    public static function getHotSessions()
3565
    {
3566
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3567
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3568
        $tbl_users = Database::get_main_table(TABLE_MAIN_USER);
3569
        $tbl_extra_fields = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3570
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3571
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
3572
3573
        $extraField = new ExtraFieldModel('session');
3574
        $field = $extraField->get_handler_field_info_by_field_variable('image');
3575
3576
        $sql = "SELECT
3577
                s.id,
3578
                s.title,
3579
                s.session_category_id,
3580
                c.title as category_name,
3581
                s.description,
3582
                s.nbr_users as users,
3583
				(SELECT COUNT(*) FROM $tbl_lp WHERE session_id = s.id) as lessons ";
3584
        if (false !== $field) {
3585
            $fieldId = $field['id'];
3586
            $sql .= ",(SELECT value FROM $tbl_extra_fields WHERE field_id = $fieldId AND item_id = s.id) as image ";
3587
        }
3588
        $sql .= " FROM $tbl_session s
3589
                LEFT JOIN $tbl_session_category c
3590
                    ON s.session_category_id = c.id
3591
                ORDER BY 8 DESC
3592
                LIMIT 8";
3593
        $result = Database::query($sql);
3594
3595
        if (Database::num_rows($result) > 0) {
3596
            $plugin = BuyCoursesPlugin::create();
3597
            $checker = $plugin->isEnabled();
3598
            $sessions = [];
3599
            while ($row = Database::fetch_assoc($result)) {
3600
                if (!isset($row['image'])) {
3601
                    $row['image'] = '';
3602
                }
3603
                $row['on_sale'] = '';
3604
                if ($checker) {
3605
                    $row['on_sale'] = $plugin->getItemByProduct(
3606
                        $row['id'],
3607
                        BuyCoursesPlugin::PRODUCT_TYPE_SESSION
3608
                    );
3609
                }
3610
                $sessions[] = $row;
3611
            }
3612
3613
            return $sessions;
3614
        }
3615
3616
        return false;
3617
    }
3618
3619
    /**
3620
     * Get all session categories (filter by access_url_id).
3621
     *
3622
     * @return mixed false if the session category does not exist, array if the session category exists
3623
     */
3624
    public static function get_all_session_category()
3625
    {
3626
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3627
        $id = api_get_current_access_url_id();
3628
        $sql = 'SELECT * FROM '.$table.'
3629
                WHERE access_url_id = '.$id.'
3630
                ORDER BY title ASC';
3631
        $result = Database::query($sql);
3632
        if (Database::num_rows($result) > 0) {
3633
            $data = Database::store_result($result, 'ASSOC');
3634
3635
            return $data;
3636
        }
3637
3638
        return false;
3639
    }
3640
3641
    /**
3642
     * Assign a coach to course in session with status = 2.
3643
     *
3644
     * @param int  $userId
3645
     * @param int  $sessionId
3646
     * @param int  $courseId
3647
     * @param bool $noCoach   optional, if is true the user don't be a coach now,
3648
     *                        otherwise it'll assign a coach
3649
     *
3650
     * @return bool true if there are affected rows, otherwise false
3651
     */
3652
    public static function set_coach_to_course_session(
3653
        $userId,
3654
        $sessionId = 0,
3655
        $courseId = 0,
3656
        $noCoach = false
3657
    ) {
3658
        $userId = (int) $userId;
3659
3660
        $sessionId = !empty($sessionId) ? (int) $sessionId : api_get_session_id();
3661
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_id();
3662
3663
        if (empty($sessionId) || empty($courseId) || empty($userId)) {
3664
            return false;
3665
        }
3666
3667
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3668
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3669
3670
        $user = api_get_user_entity($userId);
3671
3672
        if (!$user->hasRole('ROLE_TEACHER')) {
3673
            return false;
3674
        }
3675
3676
        if ($noCoach) {
3677
            // Delete the course-specific coach record
3678
            $sql = "DELETE FROM $tblSessionRelCourseRelUser
3679
                WHERE
3680
                    session_id = $sessionId AND
3681
                    c_id = $courseId AND
3682
                    user_id = $userId AND
3683
                    status = ".Session::COURSE_COACH;
3684
            $result = Database::query($sql);
3685
3686
            // Check if the user is still a coach for any course in this session
3687
            $sql = "SELECT COUNT(*) AS count FROM $tblSessionRelCourseRelUser
3688
                WHERE
3689
                    session_id = $sessionId AND
3690
                    user_id = $userId AND
3691
                    status = ".Session::COURSE_COACH;
3692
            $res = Database::query($sql);
3693
            $resultRow = Database::fetch_assoc($res);
3694
3695
            // If the user is no longer a coach for any course in this session, remove the session relationship
3696
            if (0 === (int) $resultRow['count']) {
3697
                $sql = "DELETE FROM $tblSessionRelUser
3698
                    WHERE
3699
                        session_id = $sessionId AND
3700
                        user_id = $userId AND
3701
                        relation_type = ".Session::COURSE_COACH;
3702
                Database::query($sql);
3703
            }
3704
3705
            return Database::affected_rows($result) > 0;
3706
        }
3707
3708
        // Assign user as a coach to course
3709
        // First check if the user is registered to the course
3710
        $sql = "SELECT user_id FROM $tblSessionRelCourseRelUser
3711
                WHERE
3712
                    session_id = $sessionId AND
3713
                    c_id = $courseId AND
3714
                    user_id = $userId";
3715
        $rs_check = Database::query($sql);
3716
3717
        // Then update or insert.
3718
        if (Database::num_rows($rs_check) > 0) {
3719
            $sql = "UPDATE $tblSessionRelCourseRelUser
3720
                    SET status = ".Session::COURSE_COACH."
3721
                    WHERE
3722
                        session_id = $sessionId AND
3723
                        c_id = $courseId AND
3724
                        user_id = $userId ";
3725
            $result = Database::query($sql);
3726
3727
            return Database::affected_rows($result) > 0;
3728
        }
3729
3730
        $sessionRepo = Container::getSessionRepository();
3731
3732
        $session = api_get_session_entity($sessionId);
3733
3734
        $sessionRepo->addUserInCourse(
3735
            Session::COURSE_COACH,
3736
            api_get_user_entity($userId),
3737
            api_get_course_entity($courseId),
3738
            $session
3739
        );
3740
3741
        $sessionRepo->update($session);
3742
3743
        return true;
3744
    }
3745
3746
    /**
3747
     * Subscribes sessions to human resource manager (Dashboard feature).
3748
     *
3749
     * @param array $userInfo               Human Resource Manager info
3750
     * @param array $sessions_list          Sessions id
3751
     * @param bool  $sendEmail
3752
     * @param bool  $removeSessionsFromUser
3753
     *
3754
     * @return int
3755
     * */
3756
    public static function subscribeSessionsToDrh(
3757
        $userInfo,
3758
        $sessions_list,
3759
        $sendEmail = false,
3760
        $removeSessionsFromUser = true
3761
    ) {
3762
        // Database Table Definitions
3763
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3764
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3765
3766
        if (empty($userInfo)) {
3767
            return 0;
3768
        }
3769
3770
        $userId = $userInfo['user_id'];
3771
3772
        // Only subscribe DRH users.
3773
        $rolesAllowed = [
3774
            DRH,
3775
            SESSIONADMIN,
3776
            PLATFORM_ADMIN,
3777
            COURSE_TUTOR,
3778
        ];
3779
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3780
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3781
            return 0;
3782
        }
3783
3784
        $affected_rows = 0;
3785
        // Deleting assigned sessions to hrm_id.
3786
        if ($removeSessionsFromUser) {
3787
            if (api_is_multiple_url_enabled()) {
3788
                $sql = "SELECT s.session_id
3789
                        FROM $tbl_session_rel_user s
3790
                        INNER JOIN $tbl_session_rel_access_url a
3791
                        ON (a.session_id = s.session_id)
3792
                        WHERE
3793
                            s.user_id = $userId AND
3794
                            relation_type = ".Session::DRH." AND
3795
                            access_url_id = ".api_get_current_access_url_id();
3796
            } else {
3797
                $sql = "SELECT s.session_id
3798
                        FROM $tbl_session_rel_user s
3799
                        WHERE user_id = $userId AND relation_type=".Session::DRH;
3800
            }
3801
            $result = Database::query($sql);
3802
3803
            if (Database::num_rows($result) > 0) {
3804
                while ($row = Database::fetch_array($result)) {
3805
                    $sql = "DELETE FROM $tbl_session_rel_user
3806
                            WHERE
3807
                                session_id = {$row['session_id']} AND
3808
                                user_id = $userId AND
3809
                                relation_type =".Session::DRH;
3810
                    Database::query($sql);
3811
                }
3812
            }
3813
        }
3814
3815
        // Inserting new sessions list.
3816
        if (!empty($sessions_list) && is_array($sessions_list)) {
3817
            foreach ($sessions_list as $session_id) {
3818
                $session_id = intval($session_id);
3819
                $sql = "SELECT session_id
3820
                        FROM $tbl_session_rel_user
3821
                        WHERE
3822
                            session_id = $session_id AND
3823
                            user_id = $userId AND
3824
                            relation_type = '".Session::DRH."'";
3825
                $result = Database::query($sql);
3826
                if (0 == Database::num_rows($result)) {
3827
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3828
                            VALUES (
3829
                                $session_id,
3830
                                $userId,
3831
                                '".Session::DRH."',
3832
                                '".api_get_utc_datetime()."'
3833
                            )";
3834
                    Database::query($sql);
3835
                    $affected_rows++;
3836
                }
3837
            }
3838
        }
3839
3840
        return $affected_rows;
3841
    }
3842
3843
    /**
3844
     * @param int $sessionId
3845
     *
3846
     * @return array
3847
     */
3848
    public static function getDrhUsersInSession($sessionId)
3849
    {
3850
        return self::get_users_by_session($sessionId, Session::DRH);
3851
    }
3852
3853
    /**
3854
     * @param int $userId
3855
     * @param int $sessionId
3856
     *
3857
     * @return array
3858
     */
3859
    public static function getSessionFollowedByDrh($userId, $sessionId)
3860
    {
3861
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3862
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3863
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3864
3865
        $userId = (int) $userId;
3866
        $sessionId = (int) $sessionId;
3867
3868
        $select = " SELECT * ";
3869
        if (api_is_multiple_url_enabled()) {
3870
            $sql = " $select FROM $tbl_session s
3871
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3872
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3873
                    WHERE
3874
                        sru.user_id = '$userId' AND
3875
                        sru.session_id = '$sessionId' AND
3876
                        sru.relation_type = '".Session::DRH."' AND
3877
                        access_url_id = ".api_get_current_access_url_id()."
3878
                    ";
3879
        } else {
3880
            $sql = "$select FROM $tbl_session s
3881
                     INNER JOIN $tbl_session_rel_user sru
3882
                     ON
3883
                        sru.session_id = s.id AND
3884
                        sru.user_id = '$userId' AND
3885
                        sru.session_id = '$sessionId' AND
3886
                        sru.relation_type = '".Session::DRH."'
3887
                    ";
3888
        }
3889
3890
        $result = Database::query($sql);
3891
        if (Database::num_rows($result)) {
3892
            $row = Database::fetch_assoc($result);
3893
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3894
3895
            return $row;
3896
        }
3897
3898
        return [];
3899
    }
3900
3901
    /**
3902
     * Get sessions followed by human resources manager.
3903
     *
3904
     * @param int    $userId
3905
     * @param int    $start
3906
     * @param int    $limit
3907
     * @param bool   $getCount
3908
     * @param bool   $getOnlySessionId
3909
     * @param bool   $getSql
3910
     * @param string $orderCondition
3911
     * @param string $keyword
3912
     * @param string $description
3913
     * @param array  $options
3914
     *
3915
     * @return array sessions
3916
     */
3917
    public static function get_sessions_followed_by_drh(
3918
        $userId,
3919
        $start = null,
3920
        $limit = null,
3921
        $getCount = false,
3922
        $getOnlySessionId = false,
3923
        $getSql = false,
3924
        $orderCondition = null,
3925
        $keyword = '',
3926
        $description = '',
3927
        $options = []
3928
    ) {
3929
        return self::getSessionsFollowedByUser(
3930
            $userId,
3931
            DRH,
3932
            $start,
3933
            $limit,
3934
            $getCount,
3935
            $getOnlySessionId,
3936
            $getSql,
3937
            $orderCondition,
3938
            $keyword,
3939
            $description,
3940
            $options
3941
        );
3942
    }
3943
3944
    /**
3945
     * Get sessions followed by human resources manager.
3946
     *
3947
     * @param int    $userId
3948
     * @param int    $status           DRH Optional
3949
     * @param int    $start
3950
     * @param int    $limit
3951
     * @param bool   $getCount
3952
     * @param bool   $getOnlySessionId
3953
     * @param bool   $getSql
3954
     * @param string $orderCondition
3955
     * @param string $keyword
3956
     * @param string $description
3957
     * @param array  $options
3958
     *
3959
     * @return array|string sessions
3960
     */
3961
    public static function getSessionsFollowedByUser(
3962
        $userId,
3963
        $status = null,
3964
        $start = null,
3965
        $limit = null,
3966
        $getCount = false,
3967
        $getOnlySessionId = false,
3968
        $getSql = false,
3969
        $orderCondition = null,
3970
        $keyword = '',
3971
        $description = '',
3972
        $options = []
3973
    ) {
3974
        // Database Table Definitions
3975
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3976
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3977
3978
        $extraFieldModel = new ExtraFieldModel('session');
3979
        $conditions = $extraFieldModel->parseConditions($options);
3980
        $sqlInjectJoins = $conditions['inject_joins'];
3981
        $extraFieldsConditions = $conditions['where'];
3982
        $sqlInjectWhere = $conditions['inject_where'];
3983
        $injectExtraFields = $conditions['inject_extra_fields'];
3984
3985
        if (!empty($injectExtraFields)) {
3986
            $injectExtraFields = ' , '.$injectExtraFields.' s.id';
3987
        }
3988
3989
        $userId = (int) $userId;
3990
        $user = api_get_user_entity($userId);
3991
3992
        $select = ' SELECT DISTINCT * '.$injectExtraFields;
3993
        if ($getCount) {
3994
            $select = ' SELECT count(DISTINCT(s.id)) as count ';
3995
        }
3996
3997
        if ($getOnlySessionId) {
3998
            $select = ' SELECT DISTINCT(s.id) ';
3999
        }
4000
4001
        $limitCondition = null;
4002
        if (!is_null($start) && !is_null($limit)) {
4003
            $limitCondition = " LIMIT ".intval($start).", ".intval($limit);
4004
        }
4005
4006
        if (empty($orderCondition)) {
4007
            $orderCondition = ' ORDER BY s.title ';
4008
        }
4009
4010
        $whereConditions = null;
4011
4012
        switch ($status) {
4013
            case DRH:
4014
                $sessionsQuery = array_map(
4015
                    fn(Session $session) => $session->getId(),
4016
                    $user->getDRHSessions()
4017
                );
4018
                break;
4019
            case COURSEMANAGER:
4020
                $coachSessions = array_map(
4021
                    fn(Session $session) => $session->getId(),
4022
                    $user->getSessionsByStatusInCourseSubscription(Session::COURSE_COACH)->getValues()
4023
                );
4024
                $generalCoachSessions = array_map(
4025
                    fn(Session $session) => $session->getId(),
4026
                    $user->getSessionsAsGeneralCoach()
4027
                );
4028
4029
                $sessionsQuery = array_merge($coachSessions, $generalCoachSessions);
4030
                break;
4031
            case SESSIONADMIN:
4032
                $sessionsQuery = array_map(
4033
                    fn(Session $session) => $session->getId(),
4034
                    $user->getSessionsAsAdmin()
4035
                );
4036
                break;
4037
            default:
4038
                $sessionsQuery = array_map(
4039
                    fn(Session $session) => $session->getId(),
4040
                    $user->getSessionsAsStudent()
4041
                );
4042
                break;
4043
        }
4044
4045
        $keywordCondition = '';
4046
        if (!empty($keyword)) {
4047
            $keyword = Database::escape_string($keyword);
4048
            $keywordCondition = " AND (s.title LIKE '%$keyword%' ) ";
4049
            if (!empty($description)) {
4050
                $description = Database::escape_string($description);
4051
                $keywordCondition = " AND (s.title LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
4052
            }
4053
        }
4054
4055
        $whereConditions .= $keywordCondition;
4056
        $subQuery = !empty($sessionsQuery) ? (' AND s.id IN ('.implode(',', $sessionsQuery).')') : '';
4057
4058
        $sql = " $select
4059
                FROM $tbl_session s
4060
                INNER JOIN $tbl_session_rel_access_url a
4061
                ON (s.id = a.session_id)
4062
                $sqlInjectJoins
4063
                WHERE
4064
                    access_url_id = ".api_get_current_access_url_id()."
4065
                    $subQuery
4066
                    $whereConditions
4067
                    $extraFieldsConditions
4068
                    $sqlInjectWhere
4069
                    $orderCondition
4070
                    $limitCondition";
4071
4072
        if ($getSql) {
4073
            return $sql;
4074
        }
4075
        $result = Database::query($sql);
4076
4077
        if ($getCount) {
4078
            $row = Database::fetch_array($result);
4079
            if ($row) {
4080
                return (int) $row['count'];
4081
            }
4082
4083
            return 0;
4084
        }
4085
4086
        $sessions = [];
4087
        if (Database::num_rows($result) > 0) {
4088
            $imgPath = Display::return_icon(
4089
                'session_default_small.png',
4090
                null,
4091
                [],
4092
                ICON_SIZE_SMALL,
4093
                false,
4094
                true
4095
            );
4096
4097
            $extraFieldValue = new ExtraFieldValue('session');
4098
            while ($row = Database::fetch_array($result)) {
4099
                if ($getOnlySessionId) {
4100
                    $sessions[$row['id']] = $row;
4101
                    continue;
4102
                }
4103
4104
                $extraFieldImage = $extraFieldValue->get_values_by_handler_and_field_variable($row['id'], 'image');
4105
                $image = $imgPath;
4106
                if (!empty($extraFieldImage) && isset($extraFieldImage['url'])) {
4107
                    $image = $extraFieldImage['url'];
4108
                }
4109
                $row['image'] = $image;
4110
                if ('0000-00-00 00:00:00' === $row['display_start_date'] || '0000-00-00' === $row['display_start_date']) {
4111
                    $row['display_start_date'] = null;
4112
                }
4113
4114
                if ('0000-00-00 00:00:00' === $row['display_end_date'] || '0000-00-00' === $row['display_end_date']) {
4115
                    $row['display_end_date'] = null;
4116
                }
4117
4118
                if ('0000-00-00 00:00:00' === $row['access_start_date'] || '0000-00-00' === $row['access_start_date']) {
4119
                    $row['access_start_date'] = null;
4120
                }
4121
4122
                if ('0000-00-00 00:00:00' === $row['access_end_date'] || '0000-00-00' === $row['access_end_date']) {
4123
                    $row['access_end_date'] = null;
4124
                }
4125
4126
                if ('0000-00-00 00:00:00' === $row['coach_access_start_date'] ||
4127
                    '0000-00-00' === $row['coach_access_start_date']
4128
                ) {
4129
                    $row['coach_access_start_date'] = null;
4130
                }
4131
4132
                if ('0000-00-00 00:00:00' === $row['coach_access_end_date'] ||
4133
                    '0000-00-00' === $row['coach_access_end_date']
4134
                ) {
4135
                    $row['coach_access_end_date'] = null;
4136
                }
4137
4138
                $sessions[$row['id']] = $row;
4139
            }
4140
        }
4141
4142
        return $sessions;
4143
    }
4144
4145
    /**
4146
     * Gets the list (or the count) of courses by session filtered by access_url.
4147
     *
4148
     * @param int    $session_id  The session id
4149
     * @param string $course_name The course code
4150
     * @param string $orderBy     Field to order the data
4151
     * @param bool   $getCount    Optional. Count the session courses
4152
     *
4153
     * @return array|int List of courses. Whether $getCount is true, return the count
4154
     */
4155
    public static function get_course_list_by_session_id(
4156
        $session_id,
4157
        $course_name = '',
4158
        $orderBy = null,
4159
        $getCount = false
4160
    ) {
4161
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4162
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4163
        $session_id = (int) $session_id;
4164
        $sqlSelect = '*, c.id, c.id as real_id, c.code as course_code';
4165
4166
        if ($getCount) {
4167
            $sqlSelect = 'COUNT(1) as count';
4168
        }
4169
4170
        // select the courses
4171
        $sql = "SELECT $sqlSelect
4172
                FROM $tbl_course c
4173
                INNER JOIN $tbl_session_rel_course src
4174
                ON (c.id = src.c_id)
4175
		        WHERE src.session_id = '$session_id' ";
4176
4177
        if (!empty($course_name)) {
4178
            $course_name = Database::escape_string($course_name);
4179
            $sql .= " AND c.title LIKE '%$course_name%' ";
4180
        }
4181
4182
        if (!empty($orderBy)) {
4183
            $orderBy = Database::escape_string($orderBy);
4184
            $orderBy = " ORDER BY $orderBy";
4185
        } else {
4186
            if (self::orderCourseIsEnabled()) {
4187
                $orderBy .= ' ORDER BY position ';
4188
            } else {
4189
                $orderBy .= ' ORDER BY title ';
4190
            }
4191
        }
4192
4193
        $sql .= Database::escape_string($orderBy);
4194
        $result = Database::query($sql);
4195
        $num_rows = Database::num_rows($result);
4196
        $courses = [];
4197
        if ($num_rows > 0) {
4198
            if ($getCount) {
4199
                $count = Database::fetch_assoc($result);
4200
4201
                return (int) $count['count'];
4202
            }
4203
4204
            while ($row = Database::fetch_assoc($result)) {
4205
                $courses[$row['real_id']] = $row;
4206
            }
4207
        }
4208
4209
        return $courses;
4210
    }
4211
4212
    /**
4213
     * Gets the list of courses by session filtered by access_url.
4214
     *
4215
     * @param $userId
4216
     * @param $sessionId
4217
     * @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...
4218
     * @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...
4219
     * @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...
4220
     * @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...
4221
     * @param bool   $getCount
4222
     * @param string $keyword
4223
     *
4224
     * @return array
4225
     */
4226
    public static function getAllCoursesFollowedByUser(
4227
        $userId,
4228
        $sessionId,
4229
        $from = null,
4230
        $limit = null,
4231
        $column = null,
4232
        $direction = null,
4233
        $getCount = false,
4234
        $keyword = ''
4235
    ) {
4236
        if (empty($sessionId)) {
4237
            $sessionsSQL = self::get_sessions_followed_by_drh(
4238
                $userId,
4239
                null,
4240
                null,
4241
                null,
4242
                true,
4243
                true
4244
            );
4245
        } else {
4246
            $sessionsSQL = intval($sessionId);
4247
        }
4248
4249
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4250
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4251
4252
        if ($getCount) {
4253
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
4254
        } else {
4255
            $select = "SELECT DISTINCT c.* ";
4256
        }
4257
4258
        $keywordCondition = null;
4259
        if (!empty($keyword)) {
4260
            $keyword = Database::escape_string($keyword);
4261
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4262
        }
4263
4264
        // Select the courses
4265
        $sql = "$select
4266
                FROM $tbl_course c
4267
                INNER JOIN $tbl_session_rel_course src
4268
                ON c.id = src.c_id
4269
		        WHERE
4270
		            src.session_id IN ($sessionsSQL)
4271
		            $keywordCondition
4272
		        ";
4273
        if ($getCount) {
4274
            $result = Database::query($sql);
4275
            $row = Database::fetch_assoc($result);
4276
4277
            return $row['count'];
4278
        }
4279
4280
        if (isset($from) && isset($limit)) {
4281
            $from = intval($from);
4282
            $limit = intval($limit);
4283
            $sql .= " LIMIT $from, $limit";
4284
        }
4285
4286
        $result = Database::query($sql);
4287
        $num_rows = Database::num_rows($result);
4288
        $courses = [];
4289
4290
        if ($num_rows > 0) {
4291
            while ($row = Database::fetch_assoc($result)) {
4292
                $courses[$row['id']] = $row;
4293
            }
4294
        }
4295
4296
        return $courses;
4297
    }
4298
4299
    /**
4300
     * Gets the list of courses by session filtered by access_url.
4301
     *
4302
     * @param int    $session_id
4303
     * @param string $course_name
4304
     *
4305
     * @return array list of courses
4306
     */
4307
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
4308
    {
4309
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4310
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4311
4312
        $session_id = (int) $session_id;
4313
        $course_name = Database::escape_string($course_name);
4314
4315
        // select the courses
4316
        $sql = "SELECT c.id, c.title FROM $tbl_course c
4317
                INNER JOIN $tbl_session_rel_course src
4318
                ON c.id = src.c_id
4319
		        WHERE ";
4320
4321
        if (!empty($session_id)) {
4322
            $sql .= "src.session_id LIKE '$session_id' AND ";
4323
        }
4324
4325
        if (!empty($course_name)) {
4326
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
4327
        }
4328
4329
        $sql .= "ORDER BY title;";
4330
        $result = Database::query($sql);
4331
        $num_rows = Database::num_rows($result);
4332
        $courses = [];
4333
        if ($num_rows > 0) {
4334
            while ($row = Database::fetch_assoc($result)) {
4335
                $courses[$row['id']] = $row;
4336
            }
4337
        }
4338
4339
        return $courses;
4340
    }
4341
4342
    /**
4343
     * Gets the count of courses by session filtered by access_url.
4344
     *
4345
     * @param int session id
4346
     * @param string $keyword
4347
     *
4348
     * @return array list of courses
4349
     */
4350
    public static function getCourseCountBySessionId($session_id, $keyword = '')
4351
    {
4352
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4353
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4354
        $session_id = (int) $session_id;
4355
4356
        // select the courses
4357
        $sql = "SELECT COUNT(c.code) count
4358
                FROM $tbl_course c
4359
                INNER JOIN $tbl_session_rel_course src
4360
                ON c.id = src.c_id
4361
		        WHERE src.session_id = '$session_id' ";
4362
4363
        $keywordCondition = null;
4364
        if (!empty($keyword)) {
4365
            $keyword = Database::escape_string($keyword);
4366
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4367
        }
4368
        $sql .= $keywordCondition;
4369
4370
        $result = Database::query($sql);
4371
        $num_rows = Database::num_rows($result);
4372
        if ($num_rows > 0) {
4373
            $row = Database::fetch_assoc($result);
4374
4375
            return $row['count'];
4376
        }
4377
4378
        return null;
4379
    }
4380
4381
    /**
4382
     * Get the session id based on the original id and field name in the extra fields.
4383
     * Returns 0 if session was not found.
4384
     *
4385
     * @param string $value    Original session id
4386
     * @param string $variable Original field name
4387
     *
4388
     * @return int Session id
4389
     */
4390
    public static function getSessionIdFromOriginalId($value, $variable)
4391
    {
4392
        $extraFieldValue = new ExtraFieldValue('session');
4393
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
4394
            $variable,
4395
            $value
4396
        );
4397
4398
        if (!empty($result)) {
4399
            return $result['item_id'];
4400
        }
4401
4402
        return 0;
4403
    }
4404
4405
    /**
4406
     * Get users by session.
4407
     *
4408
     * @param int  $id       session id
4409
     * @param int  $status   filter by status coach = 2
4410
     * @param bool $getCount Optional. Allow get the number of rows from the result
4411
     * @param int  $urlId
4412
     *
4413
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
4414
     */
4415
    public static function get_users_by_session(
4416
        $id,
4417
        $status = null,
4418
        $getCount = false,
4419
        $urlId = 0
4420
    ) {
4421
        if (empty($id)) {
4422
            return [];
4423
        }
4424
        $id = (int) $id;
4425
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
4426
4427
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4428
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4429
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
4430
4431
        $selectedField = '
4432
            u.id as user_id, u.lastname, u.firstname, u.username, su.relation_type, au.access_url_id,
4433
            su.moved_to, su.moved_status, su.moved_at, su.registered_at
4434
        ';
4435
4436
        if ($getCount) {
4437
            $selectedField = 'count(1) AS count';
4438
        }
4439
4440
        $sql = "SELECT $selectedField
4441
                FROM $tbl_user u
4442
                INNER JOIN $tbl_session_rel_user su
4443
                ON u.id = su.user_id AND
4444
                su.session_id = $id
4445
                LEFT OUTER JOIN $table_access_url_user au
4446
                ON (au.user_id = u.id)
4447
                ";
4448
4449
        if (is_numeric($status)) {
4450
            $status = (int) $status;
4451
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
4452
        } else {
4453
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
4454
        }
4455
4456
        $sql .= ' AND u.active <> '.USER_SOFT_DELETED.' ORDER BY su.relation_type, ';
4457
        $sql .= api_sort_by_first_name() ? ' u.firstname, u.lastname' : '  u.lastname, u.firstname';
4458
4459
        $result = Database::query($sql);
4460
        if ($getCount) {
4461
            $count = Database::fetch_assoc($result);
4462
            if ($count) {
4463
                return (int) $count['count'];
4464
            }
4465
4466
            return 0;
4467
        }
4468
4469
        $return = [];
4470
        while ($row = Database::fetch_assoc($result)) {
4471
            $return[] = $row;
4472
        }
4473
4474
        return $return;
4475
    }
4476
4477
    /**
4478
     * The general coach (session_rel_user.relation_type = Session::GENERAL_COACH).
4479
     *
4480
     * @param int  $user_id         user id
4481
     * @param bool $asPlatformAdmin The user is platform admin, return everything
4482
     *
4483
     * @return array
4484
     */
4485
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
4486
    {
4487
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
4488
        $user_id = (int) $user_id;
4489
4490
        $innerJoin = '';
4491
        $whereConditions = '';
4492
4493
        if (!$asPlatformAdmin) {
4494
            $innerJoin = " INNER JOIN session_rel_user AS sru ON (s.id = sru.session_id) ";
4495
            $whereConditions = "sru.user_id = $user_id AND sru.relation_type = ".Session::GENERAL_COACH;
4496
        }
4497
4498
        if (api_is_multiple_url_enabled()) {
4499
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4500
            $access_url_id = api_get_current_access_url_id();
4501
4502
            if (-1 != $access_url_id) {
4503
                $innerJoin .= " INNER JOIN $tblSessionRelAccessUrl session_rel_url
4504
                    ON (s.id = access_url_rel_session.session_id)";
4505
                $whereConditions .= " AND access_url_rel_session.access_url_id = $access_url_id";
4506
            }
4507
        }
4508
        $sql = "SELECT s.* FROM $sessionTable AS s $innerJoin ";
4509
        if (!empty($whereConditions)) {
4510
            $sql .= "WHERE $whereConditions ";
4511
        }
4512
        $sql .= "ORDER BY s.title";
4513
        $result = Database::query($sql);
4514
4515
        return Database::store_result($result, 'ASSOC');
4516
    }
4517
4518
    /**
4519
     * @param int $user_id
4520
     * @param int $courseId
4521
     * @param int $session_id
4522
     *
4523
     * @return array|bool
4524
     */
4525
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
4526
    {
4527
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4528
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4529
        $sql = "SELECT session_rcru.status
4530
                FROM $table session_rcru
4531
                INNER JOIN $tbl_user user
4532
                ON (session_rcru.user_id = user.id)
4533
                WHERE
4534
                    session_rcru.session_id = '".intval($session_id)."' AND
4535
                    session_rcru.c_id ='".intval($courseId)."' AND
4536
                    user.id = ".intval($user_id);
4537
4538
        $result = Database::query($sql);
4539
        $status = false;
4540
        if (Database::num_rows($result)) {
4541
            $status = Database::fetch_row($result);
4542
            $status = $status['0'];
4543
        }
4544
4545
        return $status;
4546
    }
4547
4548
    /**
4549
     * Gets user status within a session.
4550
     *
4551
     * @param int $userId
4552
     * @param int $sessionId
4553
     *
4554
     * @return SessionRelUser
4555
     */
4556
    public static function getUserStatusInSession($userId, $sessionId)
4557
    {
4558
        $em = Database::getManager();
4559
        $subscriptions = $em
4560
            ->getRepository(SessionRelUser::class)
4561
            ->findBy(['session' => $sessionId, 'user' => $userId]);
4562
4563
        /** @var SessionRelUser $subscription */
4564
        $subscription = current($subscriptions);
4565
4566
        return $subscription;
4567
    }
4568
4569
    /**
4570
     * @param int $id
4571
     *
4572
     * @return array
4573
     */
4574
    public static function get_all_sessions_by_promotion($id)
4575
    {
4576
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4577
4578
        return Database::select(
4579
            '*',
4580
            $table,
4581
            ['where' => ['promotion_id = ?' => $id]]
4582
        );
4583
    }
4584
4585
    /**
4586
     * @param int   $promotion_id
4587
     * @param array $list
4588
     */
4589
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
4590
    {
4591
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4592
        $params = [];
4593
        $params['promotion_id'] = 0;
4594
        Database::update(
4595
            $table,
4596
            $params,
4597
            ['promotion_id = ?' => $promotion_id]
4598
        );
4599
4600
        $params['promotion_id'] = $promotion_id;
4601
        if (!empty($list)) {
4602
            foreach ($list as $session_id) {
4603
                $session_id = (int) $session_id;
4604
                Database::update($table, $params, ['id = ?' => $session_id]);
4605
            }
4606
        }
4607
    }
4608
4609
    /**
4610
     * Updates a session status.
4611
     *
4612
     * @param int session id
4613
     * @param int status
4614
     */
4615
    public static function set_session_status($session_id, $status)
4616
    {
4617
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
4618
        $params['visibility'] = $status;
4619
        Database::update($t, $params, ['id = ?' => $session_id]);
4620
    }
4621
4622
    /**
4623
     * Copies a session with the same data to a new session.
4624
     * The new copy is not assigned to the same promotion.
4625
     *
4626
     * @param int  $id                         Session ID
4627
     * @param bool $copy_courses               Whether to copy the relationship with courses
4628
     * @param bool $copyTeachersAndDrh
4629
     * @param bool $create_new_courses         New courses will be created
4630
     * @param bool $set_exercises_lp_invisible Set exercises and LPs in the new session to invisible by default
4631
     * @param bool $copyWithSessionContent     Copy course session content into the courses
4632
     *
4633
     * @return int The new session ID on success, 0 otherwise
4634
     *
4635
     * @see subscribe_sessions_to_promotions() for that.
4636
     *
4637
     * @todo make sure the extra session fields are copied too
4638
     */
4639
    public static function copy(
4640
        int $id,
4641
        bool $copy_courses = true,
4642
        bool $copyTeachersAndDrh = true,
4643
        bool $create_new_courses = false,
4644
        bool $set_exercises_lp_invisible = false,
4645
        bool $copyWithSessionContent = false,
4646
    ) {
4647
        $id = (int) $id;
4648
        $s = self::fetch($id);
4649
4650
        if (empty($s)) {
4651
            return false;
4652
        }
4653
4654
        // Check all dates before copying
4655
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
4656
        $now = time() - date('Z');
4657
        // Timestamp in one month
4658
        $inOneMonth = $now + (30 * 24 * 3600);
4659
        $inOneMonth = api_get_local_time($inOneMonth);
4660
        if (api_strtotime($s['access_start_date']) < $now) {
4661
            $s['access_start_date'] = api_get_local_time($now);
4662
        } else {
4663
            $s['access_start_date'] = api_get_local_time($s['access_start_date']);
4664
        }
4665
        if (api_strtotime($s['display_start_date']) < $now) {
4666
            $s['display_start_date'] = api_get_local_time($now);
4667
        } else {
4668
            $s['display_start_date'] = api_get_local_time($s['display_start_date']);
4669
        }
4670
        if (api_strtotime($s['coach_access_start_date']) < $now) {
4671
            $s['coach_access_start_date'] = api_get_local_time($now);
4672
        } else {
4673
            $s['coach_access_start_date'] = api_get_local_time($s['coach_access_start_date']);
4674
        }
4675
        if (api_strtotime($s['access_end_date']) < $now) {
4676
            $s['access_end_date'] = $inOneMonth;
4677
        } else {
4678
            $s['access_end_date'] = api_get_local_time($s['access_end_date']);
4679
        }
4680
        if (api_strtotime($s['display_end_date']) < $now) {
4681
            $s['display_end_date'] = $inOneMonth;
4682
        } else {
4683
            $s['display_end_date'] = api_get_local_time($s['display_end_date']);
4684
        }
4685
        if (api_strtotime($s['coach_access_end_date']) < $now) {
4686
            $s['coach_access_end_date'] = $inOneMonth;
4687
        } else {
4688
            $s['coach_access_end_date'] = api_get_local_time($s['coach_access_end_date']);
4689
        }
4690
4691
        $extraFieldValue = new ExtraFieldValue('session');
4692
        $extraFieldsValues = $extraFieldValue->getAllValuesByItem($id);
4693
        $extraFieldsValuesToCopy = [];
4694
        if (!empty($extraFieldsValues)) {
4695
            foreach ($extraFieldsValues as $extraFieldValue) {
4696
                //$extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4697
                $extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']]['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4698
            }
4699
        }
4700
4701
        // @todo fix session image url copy.
4702
        /*if (isset($extraFieldsValuesToCopy['extra_image']) &&
4703
            isset($extraFieldsValuesToCopy['extra_image']['extra_image'])
4704
        ) {
4705
            $extraFieldsValuesToCopy['extra_image'] = [
4706
                'tmp_name' => api_get_path(SYS_UPLOAD_PATH).$extraFieldsValuesToCopy['extra_image']['extra_image'],
4707
                'error' => 0,
4708
            ];
4709
        }*/
4710
4711
        $generalCoaches = self::getGeneralCoachesIdForSession($id);
4712
4713
        // Now try to create the session
4714
        $sid = self::create_session(
4715
            $s['title'].' '.get_lang('Copy'),
4716
            $s['access_start_date'],
4717
            $s['access_end_date'],
4718
            $s['display_start_date'],
4719
            $s['display_end_date'],
4720
            $s['coach_access_start_date'],
4721
            $s['coach_access_end_date'],
4722
            $generalCoaches,
4723
            $s['session_category_id'],
4724
            (int) $s['visibility'],
4725
            true,
4726
            $s['duration'],
4727
            $s['description'],
4728
            $s['show_description'],
4729
            $extraFieldsValuesToCopy
4730
        );
4731
4732
        if (!is_numeric($sid) || empty($sid)) {
4733
            return false;
4734
        }
4735
4736
        if ($copy_courses) {
4737
            // Register courses from the original session to the new session
4738
            $courses = self::get_course_list_by_session_id($id);
4739
            $short_courses = $new_short_courses = [];
4740
            if (is_array($courses) && count($courses) > 0) {
4741
                foreach ($courses as $course) {
4742
                    $short_courses[] = $course;
4743
                }
4744
            }
4745
4746
            // We will copy the current courses of the session to new courses
4747
            if (!empty($short_courses)) {
4748
                if ($create_new_courses) {
4749
                    api_set_more_memory_and_time_limits();
4750
                    $params = [];
4751
                    $params['skip_lp_dates'] = true;
4752
4753
                    foreach ($short_courses as $course_data) {
4754
                        $course = CourseManager::copy_course_simple(
4755
                            $course_data['title'].' '.get_lang('Copy'),
4756
                            $course_data['course_code'],
4757
                            $id,
4758
                            $sid,
4759
                            $params
4760
                        );
4761
4762
                        if (null !== $course) {
4763
                            $course_info = api_get_course_info($course->getCode());
4764
                            //By default new elements are invisible
4765
                            if ($set_exercises_lp_invisible) {
4766
                                $list = new LearnpathList('', $course_info, $sid);
4767
                                $flat_list = $list->get_flat_list();
4768
                                if (!empty($flat_list)) {
4769
                                    foreach ($flat_list as $lp_id => $data) {
4770
                                        // @todo fix
4771
                                        /*api_item_property_update(
4772
                                            $course_info,
4773
                                            TOOL_LEARNPATH,
4774
                                            $lp_id,
4775
                                            'invisible',
4776
                                            api_get_user_id(),
4777
                                            0,
4778
                                            0,
4779
                                            0,
4780
                                            0,
4781
                                            $sid
4782
                                        );*/
4783
                                    }
4784
                                }
4785
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4786
                                $course_id = $course_info['real_id'];
4787
                                //@todo check this query
4788
                                $sql = "UPDATE $quiz_table SET active = 0
4789
                                        WHERE c_id = $course_id AND session_id = $sid";
4790
                                Database::query($sql);
4791
                            }
4792
                            $new_short_courses[] = $course_info['real_id'];
4793
                        }
4794
                    }
4795
                } else {
4796
                    foreach ($short_courses as $course_data) {
4797
                        $new_short_courses[] = $course_data['id'];
4798
                    }
4799
                }
4800
4801
                $short_courses = $new_short_courses;
4802
                self::add_courses_to_session($sid, $short_courses, true);
4803
4804
                if ($copyWithSessionContent) {
4805
                    foreach ($courses as $course) {
4806
                        CourseManager::copy_course(
4807
                            $course['code'],
4808
                            $id,
4809
                            $course['code'],
4810
                            $sid,
4811
                            [],
4812
                            false,
4813
                            true
4814
                        );
4815
                    }
4816
                }
4817
4818
                if (false === $create_new_courses && $copyTeachersAndDrh) {
4819
                    foreach ($short_courses as $courseItemId) {
4820
                        $coachList = self::getCoachesByCourseSession($id, $courseItemId);
4821
                        foreach ($coachList as $userId) {
4822
                            self::set_coach_to_course_session($userId, $sid, $courseItemId);
4823
                        }
4824
                    }
4825
                }
4826
            }
4827
        }
4828
4829
        if ($copyTeachersAndDrh) {
4830
            // Register users from the original session to the new session
4831
            $users = self::get_users_by_session($id);
4832
            if (!empty($users)) {
4833
                $userListByStatus = [];
4834
                foreach ($users as $userData) {
4835
                    $userData['relation_type'] = (int) $userData['relation_type'];
4836
                    $userListByStatus[$userData['relation_type']][] = $userData;
4837
                }
4838
4839
                foreach ($userListByStatus as $status => $userList) {
4840
                    $userList = array_column($userList, 'user_id');
4841
                    switch ($status) {
4842
                        case 0:
4843
                            /*self::subscribeUsersToSession(
4844
                                $sid,
4845
                                $userList,
4846
                                SESSION_VISIBLE_READ_ONLY,
4847
                                false,
4848
                                true
4849
                            );*/
4850
                            break;
4851
                        case 1:
4852
                            // drh users
4853
                            foreach ($userList as $drhId) {
4854
                                $userInfo = api_get_user_info($drhId);
4855
                                self::subscribeSessionsToDrh($userInfo, [$sid], false, false);
4856
                            }
4857
                            break;
4858
                    }
4859
                }
4860
            }
4861
        }
4862
4863
        return $sid;
4864
    }
4865
4866
    /**
4867
     * Get the number of sessions.
4868
     *
4869
     * @param int $access_url_id ID of the URL we want to filter on (optional)
4870
     *
4871
     * @return int Number of sessions
4872
     */
4873
    public static function count_sessions($access_url_id = 0)
4874
    {
4875
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4876
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4877
        $access_url_id = (int) $access_url_id;
4878
        $sql = "SELECT count(s.id) FROM $session_table s";
4879
        if (!empty($access_url_id)) {
4880
            $sql .= ", $access_url_rel_session_table u ".
4881
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4882
        }
4883
        $res = Database::query($sql);
4884
        $row = Database::fetch_row($res);
4885
4886
        return $row[0];
4887
    }
4888
4889
    public static function cantEditSession(?Session $session = null, bool $checkSession = true): bool
4890
    {
4891
        if (!self::allowToManageSessions()) {
4892
            return false;
4893
        }
4894
4895
        if (api_is_platform_admin() && self::allowed($session)) {
4896
            return true;
4897
        }
4898
4899
        if ($checkSession) {
4900
            if (self::allowed($session)) {
4901
                return true;
4902
            }
4903
4904
            return false;
4905
        }
4906
4907
        return true;
4908
    }
4909
4910
    /**
4911
     * Protect a session to be edited.
4912
     *
4913
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4914
     */
4915
    public static function protectSession(?Session $session = null, bool $checkSession = true)
4916
    {
4917
        if (!self::cantEditSession($session, $checkSession)) {
4918
            api_not_allowed(true);
4919
        }
4920
    }
4921
4922
    public static function allowToManageSessions(): bool
4923
    {
4924
        if (self::allowManageAllSessions()) {
4925
            return true;
4926
        }
4927
4928
        if (api_is_teacher() && 'true' === api_get_setting('allow_teachers_to_create_sessions')) {
4929
            return true;
4930
        }
4931
4932
        return false;
4933
    }
4934
4935
    /**
4936
     * @return bool
4937
     */
4938
    public static function allowOnlyMySessions()
4939
    {
4940
        if (self::allowToManageSessions() &&
4941
            !api_is_platform_admin() &&
4942
            api_is_teacher()
4943
        ) {
4944
            return true;
4945
        }
4946
4947
        return false;
4948
    }
4949
4950
    /**
4951
     * @return bool
4952
     */
4953
    public static function allowManageAllSessions()
4954
    {
4955
        if (api_is_platform_admin() || api_is_session_admin()) {
4956
            return true;
4957
        }
4958
4959
        return false;
4960
    }
4961
4962
    /**
4963
     * @param $id
4964
     *
4965
     * @return bool
4966
     */
4967
    public static function protect_teacher_session_edit($id)
4968
    {
4969
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4970
            api_not_allowed(true);
4971
        } else {
4972
            return true;
4973
        }
4974
    }
4975
4976
    /**
4977
     * @param int $courseId
4978
     *
4979
     * @return array
4980
     */
4981
    public static function get_session_by_course($courseId)
4982
    {
4983
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4984
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4985
        $url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4986
        $courseId = (int) $courseId;
4987
        $urlId = api_get_current_access_url_id();
4988
4989
        if (empty($courseId)) {
4990
            return [];
4991
        }
4992
4993
        $sql = "SELECT title, s.id
4994
                FROM $table_session_course sc
4995
                INNER JOIN $table_session s
4996
                ON (sc.session_id = s.id)
4997
                INNER JOIN $url u
4998
                ON (u.session_id = s.id)
4999
                WHERE
5000
                    u.access_url_id = $urlId AND
5001
                    sc.c_id = '$courseId' ";
5002
        $result = Database::query($sql);
5003
5004
        return Database::store_result($result);
5005
    }
5006
5007
    /**
5008
     * @param int  $userId
5009
     * @param bool $ignoreVisibilityForAdmins
5010
     * @param bool $ignoreTimeLimit
5011
     *
5012
     * @return array
5013
     */
5014
    public static function get_sessions_by_user(
5015
        $userId,
5016
        $ignoreVisibilityForAdmins = false,
5017
        $ignoreTimeLimit = false
5018
    ) {
5019
        $sessionCategories = UserManager::get_sessions_by_category(
5020
            $userId,
5021
            false,
5022
            $ignoreVisibilityForAdmins,
5023
            $ignoreTimeLimit
5024
        );
5025
5026
        $sessionArray = [];
5027
        if (!empty($sessionCategories)) {
5028
            foreach ($sessionCategories as $category) {
5029
                if (isset($category['sessions'])) {
5030
                    foreach ($category['sessions'] as $session) {
5031
                        $sessionArray[] = $session;
5032
                    }
5033
                }
5034
            }
5035
        }
5036
5037
        return $sessionArray;
5038
    }
5039
5040
    /**
5041
     * @param string $file
5042
     * @param bool   $updateSession                                   true: if the session exists it will be updated.
5043
     *                                                                false: if session exists a new session will be created adding a counter session1, session2, etc
5044
     * @param int    $defaultUserId
5045
     * @param Logger $logger
5046
     * @param array  $extraFields                                     convert a file row to an extra field. Example in CSV file there's a SessionID
5047
     *                                                                then it will converted to extra_external_session_id if you set: array('SessionId' => 'extra_external_session_id')
5048
     * @param string $extraFieldId
5049
     * @param int    $daysCoachAccessBeforeBeginning
5050
     * @param int    $daysCoachAccessAfterBeginning
5051
     * @param int    $sessionVisibility
5052
     * @param array  $fieldsToAvoidUpdate
5053
     * @param bool   $deleteUsersNotInList
5054
     * @param bool   $updateCourseCoaches
5055
     * @param bool   $sessionWithCoursesModifier
5056
     * @param bool   $addOriginalCourseTeachersAsCourseSessionCoaches
5057
     * @param bool   $removeAllTeachersFromCourse
5058
     * @param int    $showDescription
5059
     * @param array  $teacherBackupList
5060
     * @param array  $groupBackup
5061
     *
5062
     * @return array
5063
     */
5064
    public static function importCSV(
5065
        $file,
5066
        $updateSession,
5067
        $defaultUserId = null,
5068
        $logger = null,
5069
        $extraFields = [],
5070
        $extraFieldId = null,
5071
        $daysCoachAccessBeforeBeginning = null,
5072
        $daysCoachAccessAfterBeginning = null,
5073
        $sessionVisibility = 1,
5074
        $fieldsToAvoidUpdate = [],
5075
        $deleteUsersNotInList = false,
5076
        $updateCourseCoaches = false,
5077
        $sessionWithCoursesModifier = false,
5078
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
5079
        $removeAllTeachersFromCourse = true,
5080
        $showDescription = null,
5081
        &$teacherBackupList = [],
5082
        &$groupBackup = []
5083
    ) {
5084
        $content = file($file);
5085
        $error_message = null;
5086
        $session_counter = 0;
5087
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
5088
5089
        $eol = PHP_EOL;
5090
        if (PHP_SAPI != 'cli') {
5091
            $eol = '<br />';
5092
        }
5093
5094
        $debug = false;
5095
        if (isset($logger)) {
5096
            $debug = true;
5097
        }
5098
5099
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5100
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
5101
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5102
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5103
        $sessions = [];
5104
        if (!api_strstr($content[0], ';')) {
5105
            $error_message = get_lang('The specified file is not CSV format !');
5106
        } else {
5107
            $tag_names = [];
5108
            foreach ($content as $key => $enreg) {
5109
                $enreg = explode(';', trim($enreg));
5110
                if ($key) {
5111
                    foreach ($tag_names as $tag_key => $tag_name) {
5112
                        if (isset($enreg[$tag_key])) {
5113
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
5114
                        }
5115
                    }
5116
                } else {
5117
                    foreach ($enreg as $tag_name) {
5118
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
5119
                    }
5120
                    if (!in_array('SessionName', $tag_names) ||
5121
                        !in_array('DateStart', $tag_names) ||
5122
                        !in_array('DateEnd', $tag_names)
5123
                    ) {
5124
                        $error_message = get_lang('The specified file doesn\'t contain all needed data !');
5125
                        break;
5126
                    }
5127
                }
5128
            }
5129
5130
            $sessionList = [];
5131
            $report = [];
5132
5133
            // Looping the sessions.
5134
            foreach ($sessions as $enreg) {
5135
                $user_counter = 0;
5136
                $course_counter = 0;
5137
5138
                if (isset($extraFields) && !empty($extraFields)) {
5139
                    foreach ($extraFields as $original => $to) {
5140
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
5141
                    }
5142
                }
5143
5144
                $session_name = $enreg['SessionName'];
5145
5146
                if ($debug) {
5147
                    $logger->debug('---------------------------------------');
5148
                    $logger->debug("Sessions - Start process of session: $session_name");
5149
                    $logger->debug('---------------------------------------');
5150
                }
5151
5152
                // Default visibility
5153
                $visibilityAfterExpirationPerSession = $sessionVisibility;
5154
5155
                if (isset($enreg['VisibilityAfterExpiration'])) {
5156
                    $visibility = $enreg['VisibilityAfterExpiration'];
5157
                    switch ($visibility) {
5158
                        case 'read_only':
5159
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
5160
                            break;
5161
                        case 'accessible':
5162
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
5163
                            break;
5164
                        case 'not_accessible':
5165
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
5166
                            break;
5167
                    }
5168
                }
5169
5170
                if (empty($session_name)) {
5171
                    continue;
5172
                }
5173
5174
                $displayAccessStartDate = isset($enreg['DisplayStartDate']) ? $enreg['DisplayStartDate'] : $enreg['DateStart'];
5175
                $displayAccessEndDate = isset($enreg['DisplayEndDate']) ? $enreg['DisplayEndDate'] : $enreg['DateEnd'];
5176
                $coachAccessStartDate = isset($enreg['CoachStartDate']) ? $enreg['CoachStartDate'] : $enreg['DateStart'];
5177
                $coachAccessEndDate = isset($enreg['CoachEndDate']) ? $enreg['CoachEndDate'] : $enreg['DateEnd'];
5178
                // We assume the dates are already in UTC
5179
                $dateStart = explode('/', $enreg['DateStart']);
5180
                $dateEnd = explode('/', $enreg['DateEnd']);
5181
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
5182
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
5183
                $displayAccessStartDate = explode('/', $displayAccessStartDate);
5184
                $displayAccessStartDate = implode('-', $displayAccessStartDate).' 00:00:00';
5185
                $displayAccessEndDate = explode('/', $displayAccessEndDate);
5186
                $displayAccessEndDate = implode('-', $displayAccessEndDate).' 23:59:59';
5187
                $coachAccessStartDate = explode('/', $coachAccessStartDate);
5188
                $coachAccessStartDate = implode('-', $coachAccessStartDate).' 00:00:00';
5189
                $coachAccessEndDate = explode('/', $coachAccessEndDate);
5190
                $coachAccessEndDate = implode('-', $coachAccessEndDate).' 23:59:59';
5191
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
5192
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
5193
                $classes = isset($enreg['Classes']) ? explode('|', $enreg['Classes']) : [];
5194
                $extraParams = [];
5195
                if (!is_null($showDescription)) {
5196
                    $extraParams['show_description'] = intval($showDescription);
5197
                }
5198
5199
                $coachBefore = '';
5200
                $coachAfter = '';
5201
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5202
                    $date = new \DateTime($dateStart);
5203
                    $interval = new DateInterval('P'.$daysCoachAccessBeforeBeginning.'D');
5204
                    $date->sub($interval);
5205
                    $coachBefore = $date->format('Y-m-d h:i');
5206
                    $coachAccessStartDate = $coachBefore;
5207
                    $coachBefore = api_get_utc_datetime($coachBefore);
5208
5209
                    $date = new \DateTime($dateEnd);
5210
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
5211
                    $date->add($interval);
5212
                    $coachAfter = $date->format('Y-m-d h:i');
5213
                    $coachAccessEndDate = $coachAfter;
5214
                    $coachAfter = api_get_utc_datetime($coachAfter);
5215
                }
5216
5217
                $dateStart = api_get_utc_datetime($dateStart);
5218
                $dateEnd = api_get_utc_datetime($dateEnd);
5219
                $displayAccessStartDate = api_get_utc_datetime($displayAccessStartDate);
5220
                $displayAccessEndDate = api_get_utc_datetime($displayAccessEndDate);
5221
                $coachAccessStartDate = api_get_utc_datetime($coachAccessStartDate);
5222
                $coachAccessEndDate = api_get_utc_datetime($coachAccessEndDate);
5223
5224
                if (!empty($sessionDescription)) {
5225
                    $extraParams['description'] = $sessionDescription;
5226
                }
5227
5228
                if (!empty($session_category_id)) {
5229
                    $extraParams['session_category_id'] = $session_category_id;
5230
                }
5231
5232
                // Searching a general coach.
5233
                if (!empty($enreg['Coach'])) {
5234
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
5235
                    if (false === $coach_id) {
5236
                        // If the coach-user does not exist - I'm the coach.
5237
                        $coach_id = $defaultUserId;
5238
                    }
5239
                } else {
5240
                    $coach_id = $defaultUserId;
5241
                }
5242
5243
                $users = explode('|', $enreg['Users']);
5244
                $courses = explode('|', $enreg['Courses']);
5245
5246
                $deleteOnlyCourseCoaches = false;
5247
                if (1 == count($courses)) {
5248
                    if ($logger) {
5249
                        $logger->debug('Only one course delete old coach list');
5250
                    }
5251
                    $deleteOnlyCourseCoaches = true;
5252
                }
5253
5254
                if (!$updateSession) {
5255
                    // Create a session.
5256
                    $unique_name = false;
5257
                    $i = 0;
5258
                    // Change session name, verify that session doesn't exist.
5259
                    $suffix = null;
5260
                    while (!$unique_name) {
5261
                        if ($i > 1) {
5262
                            $suffix = ' - '.$i;
5263
                        }
5264
                        $sql = 'SELECT id FROM '.$tbl_session.'
5265
                                WHERE title = "'.Database::escape_string($session_name).$suffix.'"';
5266
                        $rs = Database::query($sql);
5267
                        if (Database::result($rs, 0, 0)) {
5268
                            $i++;
5269
                        } else {
5270
                            $unique_name = true;
5271
                            $session_name .= $suffix;
5272
                        }
5273
                    }
5274
5275
                    $sessionParams = [
5276
                        'title' => $session_name,
5277
                        'access_start_date' => $dateStart,
5278
                        'access_end_date' => $dateEnd,
5279
                        'display_start_date' => $displayAccessStartDate,
5280
                        'display_end_date' => $displayAccessEndDate,
5281
                        'coach_access_start_date' => $coachAccessStartDate,
5282
                        'coach_access_end_date' => $coachAccessEndDate,
5283
                        'visibility' => $visibilityAfterExpirationPerSession,
5284
                        'nbr_users' => 0,
5285
                        'nbr_courses' => 0,
5286
                        'nbr_classes' => 0,
5287
                        'status' => 0,
5288
                        'duration' => 0,
5289
                    ];
5290
5291
                    if (!empty($extraParams)) {
5292
                        $sessionParams = array_merge($sessionParams, $extraParams);
5293
                    }
5294
                    // Creating the session.
5295
                    $session_id = Database::insert($tbl_session, $sessionParams);
5296
                    if ($session_id) {
5297
                        Database::insert(
5298
                            $tbl_session_user,
5299
                            [
5300
                                'relation_type' => Session::GENERAL_COACH,
5301
                                'duration' => 0,
5302
                                'registered_at' => api_get_utc_datetime(),
5303
                                'user_id' => $coach_id,
5304
                                'session_id' => $session_id,
5305
                            ]
5306
                        );
5307
                        Database::insert(
5308
                            $tbl_session_user,
5309
                            [
5310
                                'relation_type' => Session::GENERAL_COACH,
5311
                                'duration' => 0,
5312
                                'registered_at' => api_get_utc_datetime(),
5313
                                'user_id' => $defaultUserId,
5314
                                'session_id' => $session_id,
5315
                            ]
5316
                        );
5317
                        foreach ($enreg as $key => $value) {
5318
                            if ('extra_' === substr($key, 0, 6)) { //an extra field
5319
                                self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5320
                            }
5321
                        }
5322
                        if ($debug) {
5323
                            $logger->debug("Session created: #$session_id - $session_name");
5324
                        }
5325
                    } else {
5326
                        if ($debug) {
5327
                            $message = "Sessions - Session NOT created: $session_name";
5328
                            $logger->debug($message);
5329
                            $report[] = $message;
5330
                        }
5331
                    }
5332
                    $session_counter++;
5333
                } else {
5334
                    $sessionId = null;
5335
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
5336
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
5337
                        if (empty($sessionId)) {
5338
                            $my_session_result = false;
5339
                        } else {
5340
                            $my_session_result = true;
5341
                        }
5342
                    } else {
5343
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
5344
                    }
5345
5346
                    if (false === $my_session_result) {
5347
                        // One more check
5348
                        $sessionExistsWithName = self::get_session_by_name($session_name);
5349
                        if ($sessionExistsWithName) {
5350
                            if ($debug) {
5351
                                $message = "Skip Session - Trying to update a session, but name already exists: $session_name";
5352
                                $logger->debug($message);
5353
                                $report[] = $message;
5354
                            }
5355
                            continue;
5356
                        }
5357
5358
                        $sessionParams = [
5359
                            'title' => $session_name,
5360
                            'access_start_date' => $dateStart,
5361
                            'access_end_date' => $dateEnd,
5362
                            'display_start_date' => $displayAccessStartDate,
5363
                            'display_end_date' => $displayAccessEndDate,
5364
                            'coach_access_start_date' => $coachAccessStartDate,
5365
                            'coach_access_end_date' => $coachAccessEndDate,
5366
                            'visibility' => $visibilityAfterExpirationPerSession,
5367
                            'nbr_users' => 0,
5368
                            'nbr_courses' => 0,
5369
                            'nbr_classes' => 0,
5370
                            'status' => 0,
5371
                            'duration' => 0,
5372
                        ];
5373
5374
                        if (!empty($extraParams)) {
5375
                            $sessionParams = array_merge($sessionParams, $extraParams);
5376
                        }
5377
                        $session_id = Database::insert($tbl_session, $sessionParams);
5378
5379
                        if ($session_id) {
5380
                            Database::insert(
5381
                                $tbl_session_user,
5382
                                [
5383
                                    'relation_type' => Session::GENERAL_COACH,
5384
                                    'duration' => 0,
5385
                                    'registered_at' => api_get_utc_datetime(),
5386
                                    'user_id' => $coach_id,
5387
                                    'session_id' => $session_id,
5388
                                ]
5389
                            );
5390
                            Database::insert(
5391
                                $tbl_session_user,
5392
                                [
5393
                                    'relation_type' => Session::GENERAL_COACH,
5394
                                    'duration' => 0,
5395
                                    'registered_at' => api_get_utc_datetime(),
5396
                                    'user_id' => $defaultUserId,
5397
                                    'session_id' => $session_id,
5398
                                ]
5399
                            );
5400
                            foreach ($enreg as $key => $value) {
5401
                                if ('extra_' == substr($key, 0, 6)) { //an extra field
5402
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5403
                                }
5404
                            }
5405
                            if ($debug) {
5406
                                $logger->debug("Sessions - #$session_id created: $session_name");
5407
                            }
5408
5409
                            // Delete session-user relation only for students
5410
                            $sql = "DELETE FROM $tbl_session_user
5411
                                    WHERE session_id = '$session_id' AND relation_type = ".Session::STUDENT;
5412
                            Database::query($sql);
5413
5414
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5415
                            Database::query($sql);
5416
5417
                            // Delete session-course-user relationships students and coaches.
5418
                            if ($updateCourseCoaches) {
5419
                                $sql = "DELETE FROM $tbl_session_course_user
5420
                                        WHERE session_id = '$session_id' AND status in (".Session::STUDENT.", ".Session::COURSE_COACH.")";
5421
                                Database::query($sql);
5422
                            } else {
5423
                                // Delete session-course-user relation ships *only* for students.
5424
                                $sql = "DELETE FROM $tbl_session_course_user
5425
                                        WHERE session_id = '$session_id' AND status =".Session::STUDENT;
5426
                                Database::query($sql);
5427
                            }
5428
                            if ($deleteOnlyCourseCoaches) {
5429
                                $sql = "DELETE FROM $tbl_session_course_user
5430
                                        WHERE session_id = '$session_id' AND status = ".Session::COURSE_COACH;
5431
                                Database::query($sql);
5432
                            }
5433
                        }
5434
                    } else {
5435
                        // Updating the session.
5436
                        $params = [
5437
                            'access_start_date' => $dateStart,
5438
                            'access_end_date' => $dateEnd,
5439
                            'display_start_date' => $displayAccessStartDate,
5440
                            'display_end_date' => $displayAccessEndDate,
5441
                            'coach_access_start_date' => $coachAccessStartDate,
5442
                            'coach_access_end_date' => $coachAccessEndDate,
5443
                            'visibility' => $visibilityAfterExpirationPerSession,
5444
                            'session_category_id' => $session_category_id,
5445
                        ];
5446
5447
                        if (!empty($sessionDescription)) {
5448
                            $params['description'] = $sessionDescription;
5449
                        }
5450
5451
                        if (!empty($fieldsToAvoidUpdate)) {
5452
                            foreach ($fieldsToAvoidUpdate as $field) {
5453
                                unset($params[$field]);
5454
                            }
5455
                        }
5456
5457
                        if (isset($sessionId) && !empty($sessionId)) {
5458
                            $session_id = $sessionId;
5459
                            if (!empty($enreg['SessionName'])) {
5460
                                $sessionExistsWithName = self::get_session_by_name($session_name);
5461
                                if (false === $sessionExistsWithName) {
5462
                                    $sessionName = Database::escape_string($enreg['SessionName']);
5463
                                    $sql = "UPDATE $tbl_session SET title = '$sessionName' WHERE id = $session_id";
5464
                                    Database::query($sql);
5465
                                    $logger->debug(
5466
                                        "Session #$session_id name IS updated with: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
5467
                                    );
5468
                                } else {
5469
                                    $sessionExistsBesidesMe = self::sessionNameExistBesidesMySession(
5470
                                        $session_id,
5471
                                        $session_name
5472
                                    );
5473
                                    if (true === $sessionExistsBesidesMe) {
5474
                                        if ($debug) {
5475
                                            $message = "Skip Session. Error when update session Session #$session_id Name: '$session_name'. Other session has the same name. External id: ".$enreg['extra_'.$extraFieldId];
5476
                                            $logger->debug($message);
5477
                                            $report[] = $message;
5478
                                        }
5479
                                        continue;
5480
                                    } else {
5481
                                        if ($debug) {
5482
                                            $logger->debug(
5483
                                                "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]
5484
                                            );
5485
                                        }
5486
                                    }
5487
                                }
5488
                            }
5489
                        } else {
5490
                            $my_session_result = self::get_session_by_name($session_name);
5491
                            $session_id = $my_session_result['id'];
5492
                        }
5493
5494
                        if ($debug) {
5495
                            $logger->debug("Session #$session_id to be updated: '$session_name'");
5496
                        }
5497
5498
                        if ($session_id) {
5499
                            $sessionInfo = api_get_session_info($session_id);
5500
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
5501
5502
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5503
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
5504
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
5505
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
5506
                                ) {
5507
                                    $params['coach_access_start_date'] = $coachBefore;
5508
                                }
5509
5510
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
5511
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
5512
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
5513
                                ) {
5514
                                    $params['coach_access_end_date'] = $coachAfter;
5515
                                }
5516
                            }
5517
5518
                            Database::update($tbl_session, $params, ['id = ?' => $session_id]);
5519
                            Database::delete(
5520
                                $tbl_session_user,
5521
                                ['session_id = ? AND relation_type = ?' => [$session_id, Session::GENERAL_COACH]]
5522
                            );
5523
                            Database::insert(
5524
                                $tbl_session_user,
5525
                                [
5526
                                    'relation_type' => Session::GENERAL_COACH,
5527
                                    'duration' => 0,
5528
                                    'registered_at' => api_get_utc_datetime(),
5529
                                    'user_id' => $coach_id,
5530
                                    'session_id' => $session_id,
5531
                                ]
5532
                            );
5533
5534
                            foreach ($enreg as $key => $value) {
5535
                                if ('extra_' == substr($key, 0, 6)) { //an extra field
5536
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5537
                                }
5538
                            }
5539
5540
                            if ($debug) {
5541
                                $logger->debug("Session updated #$session_id");
5542
                            }
5543
5544
                            // Delete session-user relation only for students
5545
                            $sql = "DELETE FROM $tbl_session_user
5546
                                    WHERE session_id = '$session_id' AND relation_type = ".Session::STUDENT;
5547
                            Database::query($sql);
5548
5549
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5550
                            Database::query($sql);
5551
5552
                            // Delete session-course-user relationships students and coaches.
5553
                            if ($updateCourseCoaches) {
5554
                                $sql = "DELETE FROM $tbl_session_course_user
5555
                                        WHERE session_id = '$session_id' AND status in (".Session::STUDENT.", ".Session::COURSE_COACH.")";
5556
                                Database::query($sql);
5557
                            } else {
5558
                                // Delete session-course-user relation ships *only* for students.
5559
                                $sql = "DELETE FROM $tbl_session_course_user
5560
                                        WHERE session_id = '$session_id' AND status = ".Session::STUDENT;
5561
                                Database::query($sql);
5562
                            }
5563
5564
                            if ($deleteOnlyCourseCoaches) {
5565
                                $sql = "DELETE FROM $tbl_session_course_user
5566
                                        WHERE session_id = '$session_id' AND status = ".Session::COURSE_COACH;
5567
                                Database::query($sql);
5568
                            }
5569
                        } else {
5570
                            if ($debug) {
5571
                                $logger->debug(
5572
                                    "Sessions - Session not found"
5573
                                );
5574
                            }
5575
                        }
5576
                    }
5577
                    $session_counter++;
5578
                }
5579
5580
                $sessionList[] = $session_id;
5581
5582
                // Adding the relationship "Session - User" for students
5583
                $userList = [];
5584
                if (is_array($users)) {
5585
                    $extraFieldValueCareer = new ExtraFieldValue('career');
5586
                    $careerList = isset($enreg['extra_careerid']) && !empty($enreg['extra_careerid']) ? $enreg['extra_careerid'] : [];
5587
                    $careerList = str_replace(['[', ']'], '', $careerList);
5588
                    if (!empty($careerList)) {
5589
                        $careerList = explode(',', $careerList);
5590
                        $finalCareerIdList = [];
5591
                        foreach ($careerList as $careerId) {
5592
                            $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
5593
                                'external_career_id',
5594
                                $careerId
5595
                            );
5596
                            if (isset($realCareerIdList['item_id'])) {
5597
                                $finalCareerIdList[] = $realCareerIdList['item_id'];
5598
                            }
5599
                        }
5600
                    }
5601
5602
                    foreach ($users as $user) {
5603
                        $user_id = UserManager::get_user_id_from_username($user);
5604
                        if (false !== $user_id) {
5605
                            if (!empty($finalCareerIdList)) {
5606
                                foreach ($finalCareerIdList as $careerId) {
5607
                                    UserManager::addUserCareer($user_id, $careerId);
5608
                                }
5609
                            }
5610
5611
                            $userEntity = api_get_user_entity($user_id);
5612
                            $sessionEntity = api_get_session_entity($session_id);
5613
                            $sessionEntity->addUserInSession(Session::STUDENT, $userEntity);
5614
5615
                            if ($debug) {
5616
                                $logger->debug("Adding User #$user_id ($user) to session #$session_id");
5617
                            }
5618
                            $user_counter++;
5619
                        }
5620
                    }
5621
                }
5622
5623
                if ($deleteUsersNotInList) {
5624
                    // Getting user in DB in order to compare to the new list.
5625
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
5626
                    if (!empty($usersListInDatabase)) {
5627
                        if (empty($userList)) {
5628
                            foreach ($usersListInDatabase as $userInfo) {
5629
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5630
                            }
5631
                        } else {
5632
                            foreach ($usersListInDatabase as $userInfo) {
5633
                                if (!in_array($userInfo['user_id'], $userList)) {
5634
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5635
                                }
5636
                            }
5637
                        }
5638
                    }
5639
                }
5640
5641
                // See BT#6449
5642
                $onlyAddFirstCoachOrTeacher = false;
5643
                if ($sessionWithCoursesModifier) {
5644
                    if (count($courses) >= 2) {
5645
                        // Only first teacher in course session;
5646
                        $onlyAddFirstCoachOrTeacher = true;
5647
                        // Remove all teachers from course.
5648
                        $removeAllTeachersFromCourse = false;
5649
                    }
5650
                }
5651
5652
                foreach ($courses as $course) {
5653
                    $courseArray = bracketsToArray($course);
5654
                    $course_code = $courseArray[0];
5655
5656
                    if (CourseManager::course_exists($course_code)) {
5657
                        $courseInfo = api_get_course_info($course_code);
5658
                        $courseId = $courseInfo['real_id'];
5659
5660
                        // Adding the course to a session.
5661
                        $sql = "INSERT IGNORE INTO $tbl_session_course
5662
                                SET c_id = '$courseId', session_id='$session_id'";
5663
                        Database::query($sql);
5664
5665
                        self::installCourse($session_id, $courseInfo['real_id']);
5666
5667
                        if ($debug) {
5668
                            $logger->debug("Adding course '$course_code' to session #$session_id");
5669
                        }
5670
5671
                        $course_counter++;
5672
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
5673
                        $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
5674
                        $course_users = explode(',', $course_users);
5675
                        $course_coaches = explode(',', $course_coaches);
5676
5677
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
5678
                        $addTeachersToSession = true;
5679
5680
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
5681
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
5682
                        }
5683
5684
                        // If any user provided for a course, use the users array.
5685
                        if (empty($course_users)) {
5686
                            if (!empty($userList)) {
5687
                                self::subscribe_users_to_session_course(
5688
                                    $userList,
5689
                                    $session_id,
5690
                                    $course_code
5691
                                );
5692
                                if ($debug) {
5693
                                    $msg = "Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
5694
                                    $logger->debug($msg);
5695
                                }
5696
                            }
5697
                        }
5698
5699
                        // Adding coaches to session course user.
5700
                        if (!empty($course_coaches)) {
5701
                            $savedCoaches = [];
5702
                            // only edit if add_teachers_to_sessions_courses is set.
5703
                            if ($addTeachersToSession) {
5704
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
5705
                                    // Adding course teachers as course session teachers.
5706
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
5707
                                        $course_code
5708
                                    );
5709
5710
                                    if (!empty($alreadyAddedTeachers)) {
5711
                                        $teachersToAdd = [];
5712
                                        foreach ($alreadyAddedTeachers as $user) {
5713
                                            $teachersToAdd[] = $user['username'];
5714
                                        }
5715
                                        $course_coaches = array_merge(
5716
                                            $course_coaches,
5717
                                            $teachersToAdd
5718
                                        );
5719
                                    }
5720
                                }
5721
5722
                                foreach ($course_coaches as $course_coach) {
5723
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5724
                                    if (false !== $coach_id) {
5725
                                        // Just insert new coaches
5726
                                        self::updateCoaches(
5727
                                            $session_id,
5728
                                            $courseId,
5729
                                            [$coach_id],
5730
                                            false
5731
                                        );
5732
5733
                                        if ($debug) {
5734
                                            $logger->debug("Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5735
                                        }
5736
                                        $savedCoaches[] = $coach_id;
5737
                                    } else {
5738
                                        $error_message .= get_lang('This user doesn\'t exist').' : '.$course_coach.$eol;
5739
                                    }
5740
                                }
5741
                            }
5742
5743
                            // Custom courses/session coaches
5744
                            $teacherToAdd = null;
5745
                            // Only one coach is added.
5746
                            if (true == $onlyAddFirstCoachOrTeacher) {
5747
                                if ($debug) {
5748
                                    $logger->debug("onlyAddFirstCoachOrTeacher : true");
5749
                                }
5750
5751
                                foreach ($course_coaches as $course_coach) {
5752
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5753
                                    if (false !== $coach_id) {
5754
                                        $teacherToAdd = $coach_id;
5755
                                        break;
5756
                                    }
5757
                                }
5758
5759
                                // Un subscribe everyone that's not in the list.
5760
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5761
                                if (!empty($teacherList)) {
5762
                                    foreach ($teacherList as $teacher) {
5763
                                        if ($teacherToAdd != $teacher['user_id']) {
5764
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5765
                                                    WHERE
5766
                                                        user_id = ".$teacher['user_id']." AND
5767
                                                        c_id = '".$courseId."'
5768
                                                    ";
5769
5770
                                            $result = Database::query($sql);
5771
                                            $rows = Database::num_rows($result);
5772
                                            if ($rows > 0) {
5773
                                                $userCourseData = Database::fetch_assoc($result);
5774
                                                if (!empty($userCourseData)) {
5775
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5776
                                                }
5777
                                            }
5778
5779
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5780
                                                    WHERE
5781
                                                        user_id = ".$teacher['user_id']." AND
5782
                                                        c_id = '".$courseInfo['real_id']."'
5783
                                                    ";
5784
5785
                                            $result = Database::query($sql);
5786
                                            while ($groupData = Database::fetch_assoc($result)) {
5787
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5788
                                            }
5789
5790
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5791
                                                    WHERE
5792
                                                        user_id = ".$teacher['user_id']." AND
5793
                                                        c_id = '".$courseInfo['real_id']."'
5794
                                                    ";
5795
5796
                                            $result = Database::query($sql);
5797
                                            while ($groupData = Database::fetch_assoc($result)) {
5798
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5799
                                            }
5800
5801
                                            CourseManager::unsubscribe_user(
5802
                                                $teacher['user_id'],
5803
                                                $course_code
5804
                                            );
5805
5806
                                            if ($debug) {
5807
                                                $logger->debug("Delete user #".$teacher['user_id']." from base course: $course_code");
5808
                                            }
5809
                                        }
5810
                                    }
5811
                                }
5812
5813
                                if (!empty($teacherToAdd)) {
5814
                                    self::updateCoaches(
5815
                                        $session_id,
5816
                                        $courseId,
5817
                                        [$teacherToAdd],
5818
                                        true
5819
                                    );
5820
5821
                                    if ($debug) {
5822
                                        $logger->debug("Add coach #$teacherToAdd to course $courseId and session $session_id");
5823
                                    }
5824
5825
                                    $userCourseCategory = '';
5826
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
5827
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
5828
                                    ) {
5829
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
5830
                                        $userCourseCategory = $courseUserData['user_course_cat'];
5831
                                    }
5832
5833
                                    CourseManager::subscribeUser(
5834
                                        $teacherToAdd,
5835
                                        $courseId,
5836
                                        COURSEMANAGER,
5837
                                        0,
5838
                                        $userCourseCategory
5839
                                    );
5840
5841
                                    if ($debug) {
5842
                                        $logger->debug("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
5843
                                    }
5844
5845
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
5846
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
5847
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
5848
                                    ) {
5849
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
5850
                                            GroupManager::subscribeUsers(
5851
                                                $teacherToAdd,
5852
                                                api_get_group_entity($data['group_id']),
5853
                                                $data['c_id']
5854
                                            );
5855
                                        }
5856
                                    }
5857
5858
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5859
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5860
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5861
                                    ) {
5862
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5863
                                            GroupManager::subscribeTutors(
5864
                                                $teacherToAdd,
5865
                                                api_get_group_entity($data['group_id']),
5866
                                                $data['c_id']
5867
                                            );
5868
                                        }
5869
                                    }
5870
                                }
5871
                            }
5872
5873
                            // See BT#6449#note-195
5874
                            // All coaches are added.
5875
                            if ($removeAllTeachersFromCourse) {
5876
                                if ($debug) {
5877
                                    $logger->debug("removeAllTeachersFromCourse true");
5878
                                }
5879
                                $teacherToAdd = null;
5880
                                foreach ($course_coaches as $course_coach) {
5881
                                    $coach_id = UserManager::get_user_id_from_username(
5882
                                        $course_coach
5883
                                    );
5884
                                    if (false !== $coach_id) {
5885
                                        $teacherToAdd[] = $coach_id;
5886
                                    }
5887
                                }
5888
5889
                                if (!empty($teacherToAdd)) {
5890
                                    // Deleting all course teachers and adding the only coach as teacher.
5891
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5892
5893
                                    if (!empty($teacherList)) {
5894
                                        foreach ($teacherList as $teacher) {
5895
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5896
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5897
                                                        WHERE
5898
                                                            user_id = ".$teacher['user_id']." AND
5899
                                                            c_id = '".$courseId."'
5900
                                                        ";
5901
5902
                                                $result = Database::query($sql);
5903
                                                $rows = Database::num_rows($result);
5904
                                                if ($rows > 0) {
5905
                                                    $userCourseData = Database::fetch_assoc($result);
5906
                                                    if (!empty($userCourseData)) {
5907
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5908
                                                    }
5909
                                                }
5910
5911
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5912
                                                        WHERE
5913
                                                            user_id = ".$teacher['user_id']." AND
5914
                                                            c_id = '".$courseInfo['real_id']."'
5915
                                                        ";
5916
5917
                                                $result = Database::query($sql);
5918
                                                while ($groupData = Database::fetch_assoc($result)) {
5919
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5920
                                                }
5921
5922
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5923
                                                        WHERE
5924
                                                            user_id = ".$teacher['user_id']." AND
5925
                                                            c_id = '".$courseInfo['real_id']."'
5926
                                                        ";
5927
5928
                                                $result = Database::query($sql);
5929
                                                while ($groupData = Database::fetch_assoc($result)) {
5930
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5931
                                                }
5932
5933
                                                CourseManager::unsubscribe_user(
5934
                                                    $teacher['user_id'],
5935
                                                    $course_code
5936
                                                );
5937
5938
                                                if ($debug) {
5939
                                                    $logger->debug("Delete user #".$teacher['user_id']." from base course: $course_code");
5940
                                                }
5941
                                            }
5942
                                        }
5943
                                    }
5944
5945
                                    foreach ($teacherToAdd as $teacherId) {
5946
                                        $userCourseCategory = '';
5947
                                        if (isset($teacherBackupList[$teacherId]) &&
5948
                                            isset($teacherBackupList[$teacherId][$course_code])
5949
                                        ) {
5950
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5951
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5952
                                        }
5953
5954
                                        CourseManager::subscribeUser(
5955
                                            $teacherId,
5956
                                            $courseInfo['real_id'],
5957
                                            COURSEMANAGER,
5958
                                            0,
5959
                                            $userCourseCategory
5960
                                        );
5961
5962
                                        if ($debug) {
5963
                                            $logger->debug("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5964
                                        }
5965
5966
                                        if (isset($groupBackup['user'][$teacherId]) &&
5967
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5968
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5969
                                        ) {
5970
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5971
                                                GroupManager::subscribeUsers(
5972
                                                    $teacherId,
5973
                                                    api_get_group_entity($data['group_id']),
5974
                                                    $data['c_id']
5975
                                                );
5976
                                            }
5977
                                        }
5978
5979
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5980
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5981
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5982
                                        ) {
5983
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5984
                                                GroupManager::subscribeTutors(
5985
                                                    $teacherId,
5986
                                                    api_get_group_entity($data['group_id']),
5987
                                                    $data['c_id']
5988
                                                );
5989
                                            }
5990
                                        }
5991
                                    }
5992
                                }
5993
                            }
5994
5995
                            // Continue default behaviour.
5996
                            if (false == $onlyAddFirstCoachOrTeacher) {
5997
                                // Checking one more time see BT#6449#note-149
5998
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
5999
                                // Update coaches if only there's 1 course see BT#6449#note-189
6000
                                if (empty($coaches) || 1 == count($courses)) {
6001
                                    foreach ($course_coaches as $course_coach) {
6002
                                        $course_coach = trim($course_coach);
6003
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
6004
                                        if (false !== $coach_id) {
6005
                                            // Just insert new coaches
6006
                                            self::updateCoaches(
6007
                                                $session_id,
6008
                                                $courseId,
6009
                                                [$coach_id],
6010
                                                false
6011
                                            );
6012
6013
                                            if ($debug) {
6014
                                                $logger->debug("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
6015
                                            }
6016
                                            $savedCoaches[] = $coach_id;
6017
                                        } else {
6018
                                            $error_message .= get_lang('This user doesn\'t exist').' : '.$course_coach.$eol;
6019
                                        }
6020
                                    }
6021
                                }
6022
                            }
6023
                        }
6024
6025
                        // Adding Students, updating relationship "Session - Course - User".
6026
                        $course_users = array_filter($course_users);
6027
                        if (!empty($course_users)) {
6028
                            foreach ($course_users as $user) {
6029
                                $user_id = UserManager::get_user_id_from_username($user);
6030
6031
                                if (false !== $user_id) {
6032
                                    self::subscribe_users_to_session_course(
6033
                                        [$user_id],
6034
                                        $session_id,
6035
                                        $course_code
6036
                                    );
6037
                                    if ($debug) {
6038
                                        $logger->debug("Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
6039
                                    }
6040
                                } else {
6041
                                    $error_message .= get_lang('This user doesn\'t exist').': '.$user.$eol;
6042
                                }
6043
                            }
6044
                        }
6045
                        $inserted_in_course[$course_code] = $courseInfo['title'];
6046
                    }
6047
                }
6048
                $access_url_id = api_get_current_access_url_id();
6049
                UrlManager::add_session_to_url($session_id, $access_url_id);
6050
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter'
6051
                        WHERE id = '$session_id'";
6052
                Database::query($sql);
6053
6054
                self::addClassesByName($session_id, $classes, false);
6055
6056
                if ($debug) {
6057
                    $logger->debug("End process session #$session_id -------------------- ");
6058
                }
6059
            }
6060
6061
            if (!empty($report)) {
6062
                if ($debug) {
6063
                    $logger->debug("--Summary--");
6064
                    foreach ($report as $line) {
6065
                        $logger->debug($line);
6066
                    }
6067
                }
6068
            }
6069
        }
6070
6071
        return [
6072
            'error_message' => $error_message,
6073
            'session_counter' => $session_counter,
6074
            'session_list' => $sessionList,
6075
        ];
6076
    }
6077
6078
    /**
6079
     * @param int $sessionId
6080
     * @param int $courseId
6081
     *
6082
     * @return array
6083
     */
6084
    public static function getCoachesByCourseSession($sessionId, $courseId)
6085
    {
6086
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6087
        $sessionId = (int) $sessionId;
6088
        $courseId = (int) $courseId;
6089
6090
        $sql = "SELECT user_id FROM $table
6091
                WHERE
6092
                    session_id = '$sessionId' AND
6093
                    c_id = '$courseId' AND
6094
                    status = ".Session::COURSE_COACH;
6095
        $result = Database::query($sql);
6096
6097
        $coaches = [];
6098
        if (Database::num_rows($result) > 0) {
6099
            while ($row = Database::fetch_array($result)) {
6100
                $coaches[] = $row['user_id'];
6101
            }
6102
        }
6103
6104
        return $coaches;
6105
    }
6106
6107
    /**
6108
     * @param int    $sessionId
6109
     * @param int    $courseId
6110
     * @param string $separator
6111
     *
6112
     * @return string
6113
     */
6114
    public static function getCoachesByCourseSessionToString(
6115
        $sessionId,
6116
        $courseId,
6117
        $separator = ''
6118
    ) {
6119
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
6120
        $list = [];
6121
        if (!empty($coaches)) {
6122
            foreach ($coaches as $coachId) {
6123
                $userInfo = api_get_user_info($coachId);
6124
                if ($userInfo) {
6125
                    $list[] = $userInfo['complete_name'];
6126
                }
6127
            }
6128
        }
6129
6130
        $separator = empty($separator) ? CourseManager::USER_SEPARATOR : $separator;
6131
6132
        return array_to_string($list, $separator);
6133
    }
6134
6135
    /**
6136
     * Get all coaches added in the session - course relationship.
6137
     *
6138
     * @param int $sessionId
6139
     *
6140
     * @return array
6141
     */
6142
    public static function getCoachesBySession($sessionId)
6143
    {
6144
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6145
        $sessionId = intval($sessionId);
6146
6147
        $sql = "SELECT DISTINCT user_id
6148
                FROM $table
6149
                WHERE session_id = '$sessionId' AND status = ".Session::COURSE_COACH;
6150
        $result = Database::query($sql);
6151
6152
        $coaches = [];
6153
        if (Database::num_rows($result) > 0) {
6154
            while ($row = Database::fetch_array($result)) {
6155
                $coaches[] = $row['user_id'];
6156
            }
6157
        }
6158
6159
        return $coaches;
6160
    }
6161
6162
    /**
6163
     * @param int $userId
6164
     *
6165
     * @return array
6166
     */
6167
    public static function getAllCoursesFromAllSessionFromDrh($userId)
6168
    {
6169
        $sessions = self::get_sessions_followed_by_drh($userId);
6170
        $coursesFromSession = [];
6171
        if (!empty($sessions)) {
6172
            foreach ($sessions as $session) {
6173
                $courseList = self::get_course_list_by_session_id($session['id']);
6174
                foreach ($courseList as $course) {
6175
                    $coursesFromSession[] = $course['code'];
6176
                }
6177
            }
6178
        }
6179
6180
        return $coursesFromSession;
6181
    }
6182
6183
    /**
6184
     * getAllCoursesFromAllSessions.
6185
     *
6186
     * @return array
6187
     */
6188
    public static function getAllCoursesFromAllSessions()
6189
    {
6190
        $sessions = self::get_sessions_list();
6191
        $coursesFromSession = [];
6192
        if (!empty($sessions)) {
6193
            foreach ($sessions as $session) {
6194
                $courseList = self::get_course_list_by_session_id($session['id']);
6195
                foreach ($courseList as $course) {
6196
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'].' - '.$course['title'].' ('.$session['title'].')';
6197
                }
6198
            }
6199
        }
6200
6201
        return $coursesFromSession;
6202
    }
6203
6204
    /**
6205
     * Return user id list or count of users depending of the $getCount parameter.
6206
     *
6207
     * @param string $status
6208
     * @param int    $userId
6209
     * @param bool   $getCount
6210
     * @param int    $from
6211
     * @param int    $numberItems
6212
     * @param string $column
6213
     * @param string $direction
6214
     * @param string $keyword
6215
     * @param string $active
6216
     * @param string $lastConnectionDate
6217
     * @param array  $sessionIdList
6218
     * @param array  $studentIdList
6219
     * @param int    $filterByStatus
6220
     *
6221
     * @return array|int
6222
     */
6223
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
6224
        $status,
6225
        $userId,
6226
        $getCount = false,
6227
        $from = null,
6228
        $numberItems = null,
6229
        $column = '',
6230
        $direction = 'asc',
6231
        $keyword = null,
6232
        $active = null,
6233
        $lastConnectionDate = null,
6234
        $sessionIdList = [],
6235
        $studentIdList = [],
6236
        $filterByStatus = null
6237
    ) {
6238
        $filterByStatus = (int) $filterByStatus;
6239
        $userId = (int) $userId;
6240
6241
        if (empty($column)) {
6242
            $column = 'u.lastname';
6243
            if (api_is_western_name_order()) {
6244
                $column = 'u.firstname';
6245
            }
6246
        }
6247
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
6248
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
6249
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
6250
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6251
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
6252
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
6253
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6254
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6255
6256
        $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : 'asc';
6257
        $column = Database::escape_string($column);
6258
6259
        $urlId = api_get_current_access_url_id();
6260
6261
        $sessionConditions = '';
6262
        $courseConditions = '';
6263
        $userConditions = ' AND u.active <> '.USER_SOFT_DELETED.' ';
6264
6265
        if (isset($active)) {
6266
            $active = (int) $active;
6267
            $userConditions .= " AND active = $active";
6268
        }
6269
6270
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
6271
        if (!empty($courseList)) {
6272
            $courseIdList = array_column($courseList, 'id');
6273
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
6274
        }
6275
6276
        $userConditionsFromDrh = '';
6277
6278
        // Classic DRH
6279
        if (empty($studentIdList)) {
6280
            $studentListSql = UserManager::get_users_followed_by_drh(
6281
                $userId,
6282
                $filterByStatus,
6283
                true,
6284
                false
6285
            );
6286
            if (!empty($studentListSql)) {
6287
                $studentIdList = array_keys($studentListSql);
6288
                $studentListSql = "'".implode("','", $studentIdList)."'";
6289
            }
6290
        } else {
6291
            $studentIdList = array_map('intval', $studentIdList);
6292
            $studentListSql = "'".implode("','", $studentIdList)."'";
6293
        }
6294
        if (!empty($studentListSql)) {
6295
            $userConditionsFromDrh = " AND u.id IN ($studentListSql) ";
6296
        }
6297
6298
        switch ($status) {
6299
            case 'admin':
6300
            case 'drh':
6301
                break;
6302
            case 'drh_all':
6303
                // Show all by DRH
6304
                if (empty($sessionIdList)) {
6305
                    $sessionListFollowed = self::get_sessions_followed_by_drh(
6306
                        $userId,
6307
                        null,
6308
                        null,
6309
                        false,
6310
                        true
6311
                    );
6312
6313
                    if (!empty($sessionListFollowed)) {
6314
                        $sessionIdList = array_column($sessionListFollowed, 'id');
6315
                    }
6316
                }
6317
6318
                if (!empty($sessionIdList)) {
6319
                    $sessionIdList = array_map('intval', $sessionIdList);
6320
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
6321
                    $sessionConditions = " AND s.id IN ($sessionsListSql) ";
6322
                }
6323
6324
                break;
6325
            case 'teacher':
6326
            case 'session_admin':
6327
                $generalCoachedSessions = array_map(
6328
                    fn(Session $session) => $session->getId(),
6329
                    api_get_user_entity($userId)->getSessionsAsGeneralCoach()
6330
                );
6331
6332
                $sessionConditions = " AND s.IN (".implode(',', $generalCoachedSessions).") ";
6333
                $userConditionsFromDrh = '';
6334
                break;
6335
        }
6336
6337
        $select = 'SELECT DISTINCT u.*, u.id as user_id';
6338
        $masterSelect = 'SELECT DISTINCT id, id as user_id FROM ';
6339
6340
        if ($getCount) {
6341
            $select = 'SELECT DISTINCT u.id, u.id as user_id';
6342
            $masterSelect = 'SELECT COUNT(DISTINCT(id)) as count FROM ';
6343
        }
6344
6345
        if (!empty($filterByStatus)) {
6346
            $userConditions .= " AND u.status = $filterByStatus";
6347
        }
6348
6349
        if (!empty($lastConnectionDate)) {
6350
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
6351
            $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
6352
        }
6353
6354
        if (!empty($keyword)) {
6355
            $keyword = Database::escape_string($keyword);
6356
            $userConditions .= " AND (
6357
                u.username LIKE '%$keyword%' OR
6358
                u.firstname LIKE '%$keyword%' OR
6359
                u.lastname LIKE '%$keyword%' OR
6360
                u.official_code LIKE '%$keyword%' OR
6361
                u.email LIKE '%$keyword%'
6362
            )";
6363
        }
6364
6365
        $where = " WHERE
6366
                   access_url_id = $urlId
6367
                   $userConditions
6368
        ";
6369
6370
        $userUnion = '';
6371
        if (!empty($userConditionsFromDrh)) {
6372
            $userUnion = "
6373
            UNION (
6374
                $select
6375
                FROM $tbl_user u
6376
                INNER JOIN $tbl_user_rel_access_url url
6377
                ON (url.user_id = u.id)
6378
                $where
6379
                $userConditionsFromDrh
6380
            )";
6381
        }
6382
6383
        $sql = "$masterSelect (
6384
                ($select
6385
                FROM $tbl_session s
6386
                    INNER JOIN $tbl_session_rel_access_url url
6387
                    ON (url.session_id = s.id)
6388
                    INNER JOIN $tbl_session_rel_course_rel_user su
6389
                    ON (s.id = su.session_id)
6390
                    INNER JOIN $tbl_user u
6391
                    ON (u.id = su.user_id)
6392
                    $where
6393
                    $sessionConditions
6394
                    $userConditionsFromDrh
6395
                ) UNION (
6396
                    $select
6397
                    FROM $tbl_course c
6398
                    INNER JOIN $tbl_course_rel_access_url url
6399
                    ON (url.c_id = c.id)
6400
                    INNER JOIN $tbl_course_user cu
6401
                    ON (cu.c_id = c.id)
6402
                    INNER JOIN $tbl_user u
6403
                    ON (u.id = cu.user_id)
6404
                    $where
6405
                    $courseConditions
6406
                    $userConditionsFromDrh
6407
                ) $userUnion
6408
                ) as t1
6409
                ";
6410
6411
        if ($getCount) {
6412
            $result = Database::query($sql);
6413
6414
            $count = 0;
6415
            if (Database::num_rows($result)) {
6416
                $rows = Database::fetch_array($result);
6417
                $count = $rows['count'];
6418
            }
6419
6420
            return $count;
6421
        }
6422
6423
        if (!empty($column) && !empty($direction)) {
6424
            $column = str_replace('u.', '', $column);
6425
            $sql .= " ORDER BY `$column` $direction ";
6426
        }
6427
6428
        $limitCondition = '';
6429
        if (isset($from) && isset($numberItems)) {
6430
            $from = (int) $from;
6431
            $numberItems = (int) $numberItems;
6432
            $limitCondition = "LIMIT $from, $numberItems";
6433
        }
6434
6435
        $sql .= $limitCondition;
6436
        $result = Database::query($sql);
6437
6438
        return Database::store_result($result);
6439
    }
6440
6441
    /**
6442
     * @param int   $sessionId
6443
     * @param int   $courseId
6444
     * @param array $coachList
6445
     * @param bool  $deleteCoachesNotInList
6446
     */
6447
    public static function updateCoaches(
6448
        $sessionId,
6449
        $courseId,
6450
        $coachList,
6451
        $deleteCoachesNotInList = false
6452
    ) {
6453
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
6454
6455
        if (!empty($coachList)) {
6456
            foreach ($coachList as $userId) {
6457
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
6458
            }
6459
        }
6460
6461
        if ($deleteCoachesNotInList) {
6462
            if (!empty($coachList)) {
6463
                $coachesToDelete = array_diff($currentCoaches, $coachList);
6464
            } else {
6465
                $coachesToDelete = $currentCoaches;
6466
            }
6467
6468
            if (!empty($coachesToDelete)) {
6469
                foreach ($coachesToDelete as $userId) {
6470
                    self::set_coach_to_course_session(
6471
                        $userId,
6472
                        $sessionId,
6473
                        $courseId,
6474
                        true
6475
                    );
6476
                }
6477
            }
6478
        }
6479
    }
6480
6481
    /**
6482
     * @param array $sessions
6483
     * @param array $sessionsDestination
6484
     *
6485
     * @return array
6486
     */
6487
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
6488
    {
6489
        $messages = [];
6490
        if (!empty($sessions)) {
6491
            foreach ($sessions as $sessionId) {
6492
                $sessionInfo = self::fetch($sessionId);
6493
                $userList = self::get_users_by_session($sessionId, 0);
6494
                if (!empty($userList)) {
6495
                    $newUserList = [];
6496
                    $userToString = null;
6497
                    foreach ($userList as $userInfo) {
6498
                        $newUserList[] = $userInfo['user_id'];
6499
                        $userToString .= $userInfo['firstname'].' '.$userInfo['lastname'].'<br />';
6500
                    }
6501
6502
                    if (!empty($sessionsDestination)) {
6503
                        foreach ($sessionsDestination as $sessionDestinationId) {
6504
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
6505
                            $messages[] = Display::return_message(
6506
                                sprintf(
6507
                                    get_lang(
6508
                                        'AddingStudentsFromSessionXToSessionY'
6509
                                    ),
6510
                                    $sessionInfo['title'],
6511
                                    $sessionDestinationInfo['title']
6512
                                ),
6513
                                'info',
6514
                                false
6515
                            );
6516
                            if ($sessionId == $sessionDestinationId) {
6517
                                $messages[] = Display::return_message(
6518
                                    sprintf(
6519
                                        get_lang('Session %s skipped'),
6520
                                        $sessionDestinationId
6521
                                    ),
6522
                                    'warning',
6523
                                    false
6524
                                );
6525
                                continue;
6526
                            }
6527
                            $messages[] = Display::return_message(get_lang('Learners list').'<br />'.$userToString, 'info', false);
6528
                            self::subscribeUsersToSession(
6529
                                $sessionDestinationId,
6530
                                $newUserList,
6531
                                SESSION_VISIBLE_READ_ONLY,
6532
                                false
6533
                            );
6534
                        }
6535
                    } else {
6536
                        $messages[] = Display::return_message(get_lang('No destination session provided'), 'warning');
6537
                    }
6538
                } else {
6539
                    $messages[] = Display::return_message(
6540
                        get_lang('No student found for the session').' #'.$sessionInfo['title'],
6541
                        'warning'
6542
                    );
6543
                }
6544
            }
6545
        } else {
6546
            $messages[] = Display::return_message(get_lang('No data available'), 'warning');
6547
        }
6548
6549
        return $messages;
6550
    }
6551
6552
    /**
6553
     * Assign coaches of a session(s) as teachers to a given course (or courses).
6554
     *
6555
     * @param array A list of session IDs
6556
     * @param array A list of course IDs
6557
     *
6558
     * @return string
6559
     */
6560
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
6561
    {
6562
        $coachesPerSession = [];
6563
        foreach ($sessions as $sessionId) {
6564
            $coaches = self::getCoachesBySession($sessionId);
6565
            $coachesPerSession[$sessionId] = $coaches;
6566
        }
6567
6568
        $result = [];
6569
6570
        if (!empty($courses)) {
6571
            foreach ($courses as $courseId) {
6572
                $courseInfo = api_get_course_info_by_id($courseId);
6573
                foreach ($coachesPerSession as $sessionId => $coachList) {
6574
                    CourseManager::updateTeachers(
6575
                        $courseInfo,
6576
                        $coachList,
6577
                        false,
6578
                        false,
6579
                        false
6580
                    );
6581
                    $result[$courseInfo['code']][$sessionId] = $coachList;
6582
                }
6583
            }
6584
        }
6585
        $sessionUrl = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session=';
6586
        $htmlResult = null;
6587
6588
        if (!empty($result)) {
6589
            foreach ($result as $courseCode => $data) {
6590
                $url = api_get_course_url($courseCode);
6591
                $htmlResult .= sprintf(
6592
                    get_lang('Coaches subscribed as teachers in course %s'),
6593
                    Display::url($courseCode, $url, ['target' => '_blank'])
6594
                );
6595
                foreach ($data as $sessionId => $coachList) {
6596
                    $sessionInfo = self::fetch($sessionId);
6597
                    $htmlResult .= '<br />';
6598
                    $htmlResult .= Display::url(
6599
                        get_lang('Session').': '.$sessionInfo['title'].' <br />',
6600
                        $sessionUrl.$sessionId,
6601
                        ['target' => '_blank']
6602
                    );
6603
                    $teacherList = [];
6604
                    foreach ($coachList as $coachId) {
6605
                        $userInfo = api_get_user_info($coachId);
6606
                        $teacherList[] = $userInfo['complete_name'];
6607
                    }
6608
                    if (!empty($teacherList)) {
6609
                        $htmlResult .= implode(', ', $teacherList);
6610
                    } else {
6611
                        $htmlResult .= get_lang('Nothing to add');
6612
                    }
6613
                }
6614
                $htmlResult .= '<br />';
6615
            }
6616
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
6617
        }
6618
6619
        return $htmlResult;
6620
    }
6621
6622
    /**
6623
     * @param string $keyword
6624
     * @param string $active
6625
     * @param string $lastConnectionDate
6626
     * @param array  $sessionIdList
6627
     * @param array  $studentIdList
6628
     * @param int    $filterUserStatus   STUDENT|COURSEMANAGER constants
6629
     *
6630
     * @return array|int
6631
     */
6632
    public static function getCountUserTracking(
6633
        $keyword = null,
6634
        $active = null,
6635
        $lastConnectionDate = null,
6636
        $sessionIdList = [],
6637
        $studentIdList = [],
6638
        $filterUserStatus = null
6639
    ) {
6640
        $userId = api_get_user_id();
6641
        $drhLoaded = false;
6642
6643
        if (api_is_drh()) {
6644
            if (api_drh_can_access_all_session_content()) {
6645
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
6646
                    'drh_all',
6647
                    $userId,
6648
                    true,
6649
                    null,
6650
                    null,
6651
                    null,
6652
                    null,
6653
                    $keyword,
6654
                    $active,
6655
                    $lastConnectionDate,
6656
                    $sessionIdList,
6657
                    $studentIdList,
6658
                    $filterUserStatus
6659
                );
6660
                $drhLoaded = true;
6661
            }
6662
        }
6663
6664
        if (false == $drhLoaded) {
6665
            $count = UserManager::getUsersFollowedByUser(
6666
                $userId,
6667
                $filterUserStatus,
6668
                false,
6669
                false,
6670
                true,
6671
                null,
6672
                null,
6673
                null,
6674
                null,
6675
                $active,
6676
                $lastConnectionDate,
6677
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
6678
                $keyword
6679
            );
6680
        }
6681
6682
        return $count;
6683
    }
6684
6685
    /**
6686
     * Get teachers followed by a user.
6687
     *
6688
     * @param int    $userId
6689
     * @param int    $active
6690
     * @param string $lastConnectionDate
6691
     * @param bool   $getCount
6692
     * @param array  $sessionIdList
6693
     *
6694
     * @return array|int
6695
     */
6696
    public static function getTeacherTracking(
6697
        $userId,
6698
        $active = 1,
6699
        $lastConnectionDate = null,
6700
        $getCount = false,
6701
        $sessionIdList = []
6702
    ) {
6703
        $teacherListId = [];
6704
        if (api_is_drh() || api_is_platform_admin()) {
6705
            // Followed teachers by drh
6706
            if (api_drh_can_access_all_session_content()) {
6707
                if (empty($sessionIdList)) {
6708
                    $sessions = self::get_sessions_followed_by_drh($userId);
6709
                    $sessionIdList = [];
6710
                    foreach ($sessions as $session) {
6711
                        $sessionIdList[] = $session['id'];
6712
                    }
6713
                }
6714
6715
                $sessionIdList = array_map('intval', $sessionIdList);
6716
                $sessionToString = implode("', '", $sessionIdList);
6717
6718
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
6719
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6720
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6721
6722
                // Select the teachers.
6723
                $sql = "SELECT DISTINCT(cu.user_id)
6724
                        FROM $course c
6725
                        INNER JOIN $sessionCourse src
6726
                        ON c.id = src.c_id
6727
                        INNER JOIN $courseUser cu
6728
                        ON (cu.c_id = c.id)
6729
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
6730
                $result = Database::query($sql);
6731
                while ($row = Database::fetch_assoc($result)) {
6732
                    $teacherListId[$row['user_id']] = $row['user_id'];
6733
                }
6734
            } else {
6735
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
6736
                foreach ($teacherResult as $userInfo) {
6737
                    $teacherListId[] = $userInfo['user_id'];
6738
                }
6739
            }
6740
        }
6741
6742
        if (!empty($teacherListId)) {
6743
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6744
6745
            $select = "SELECT DISTINCT u.* ";
6746
            if ($getCount) {
6747
                $select = "SELECT count(DISTINCT(u.id)) as count";
6748
            }
6749
6750
            $sql = "$select FROM $tableUser u";
6751
6752
            if (!empty($lastConnectionDate)) {
6753
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6754
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
6755
            }
6756
            $active = intval($active);
6757
            $teacherListId = implode("','", $teacherListId);
6758
            $where = " WHERE u.active = $active AND u.id IN ('$teacherListId') ";
6759
6760
            if (!empty($lastConnectionDate)) {
6761
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
6762
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
6763
            }
6764
6765
            $sql .= $where;
6766
            $result = Database::query($sql);
6767
            if (Database::num_rows($result)) {
6768
                if ($getCount) {
6769
                    $row = Database::fetch_array($result);
6770
6771
                    return $row['count'];
6772
                } else {
6773
                    return Database::store_result($result, 'ASSOC');
6774
                }
6775
            }
6776
        }
6777
6778
        return 0;
6779
    }
6780
6781
    /**
6782
     * Get the list of course tools that have to be dealt with in case of
6783
     * registering any course to a session.
6784
     *
6785
     * @return array The list of tools to be dealt with (literal names)
6786
     */
6787
    public static function getCourseToolToBeManaged()
6788
    {
6789
        return [
6790
            'courseDescription',
6791
            'courseIntroduction',
6792
        ];
6793
    }
6794
6795
    /**
6796
     * Calls the methods bound to each tool when a course is registered into a session.
6797
     *
6798
     * @param int $sessionId
6799
     * @param int $courseId
6800
     *
6801
     * @return bool
6802
     */
6803
    public static function installCourse($sessionId, $courseId)
6804
    {
6805
        return true;
6806
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
6807
6808
        foreach ($toolList as $tool) {
6809
            $method = 'add'.$tool;
6810
            if (method_exists(get_class(), $method)) {
6811
                self::$method($sessionId, $courseId);
6812
            }
6813
        }
6814
    }
6815
6816
    /**
6817
     * Calls the methods bound to each tool when a course is unregistered from
6818
     * a session.
6819
     *
6820
     * @param int $sessionId
6821
     * @param int $courseId
6822
     */
6823
    public static function unInstallCourse($sessionId, $courseId)
6824
    {
6825
        return true;
6826
        $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...
6827
6828
        foreach ($toolList as $tool) {
6829
            $method = 'remove'.$tool;
6830
            if (method_exists(get_class(), $method)) {
6831
                self::$method($sessionId, $courseId);
6832
            }
6833
        }
6834
    }
6835
6836
    /**
6837
     * @param array $userSessionList        format see self::importSessionDrhCSV()
6838
     * @param bool  $sendEmail
6839
     * @param bool  $removeOldRelationShips
6840
     */
6841
    public static function subscribeDrhToSessionList(
6842
        $userSessionList,
6843
        $sendEmail,
6844
        $removeOldRelationShips
6845
    ) {
6846
        if (!empty($userSessionList)) {
6847
            foreach ($userSessionList as $userId => $data) {
6848
                $sessionList = [];
6849
                foreach ($data['session_list'] as $sessionInfo) {
6850
                    $sessionList[] = $sessionInfo['session_id'];
6851
                }
6852
                $userInfo = $data['user_info'];
6853
                self::subscribeSessionsToDrh(
6854
                    $userInfo,
6855
                    $sessionList,
6856
                    $sendEmail,
6857
                    $removeOldRelationShips
6858
                );
6859
            }
6860
        }
6861
    }
6862
6863
    /**
6864
     * @param array $userSessionList format see self::importSessionDrhCSV()
6865
     *
6866
     * @return string
6867
     */
6868
    public static function checkSubscribeDrhToSessionList($userSessionList)
6869
    {
6870
        $message = null;
6871
        if (!empty($userSessionList)) {
6872
            if (!empty($userSessionList)) {
6873
                foreach ($userSessionList as $userId => $data) {
6874
                    $userInfo = $data['user_info'];
6875
6876
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
6877
                    if (!empty($sessionListSubscribed)) {
6878
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
6879
                    }
6880
6881
                    $sessionList = [];
6882
                    if (!empty($data['session_list'])) {
6883
                        foreach ($data['session_list'] as $sessionInfo) {
6884
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
6885
                                $sessionList[] = $sessionInfo['session_info']['title'];
6886
                            }
6887
                        }
6888
                    }
6889
6890
                    $message .= '<strong>'.get_lang('User').'</strong>: ';
6891
                    $message .= $userInfo['complete_name_with_username'].' <br />';
6892
6893
                    if (!in_array($userInfo['status'], [DRH]) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6894
                        $message .= get_lang('Users must have the HR director role').'<br />';
6895
                        continue;
6896
                    }
6897
6898
                    if (!empty($sessionList)) {
6899
                        $message .= '<strong>'.get_lang('Course sessions').':</strong> <br />';
6900
                        $message .= implode(', ', $sessionList).'<br /><br />';
6901
                    } else {
6902
                        $message .= get_lang('No session provided').' <br /><br />';
6903
                    }
6904
                }
6905
            }
6906
        }
6907
6908
        return $message;
6909
    }
6910
6911
    /**
6912
     * @param string $file
6913
     * @param bool   $sendEmail
6914
     * @param bool   $removeOldRelationShips
6915
     *
6916
     * @return string
6917
     */
6918
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6919
    {
6920
        $list = Import::csv_reader($file);
6921
6922
        if (!empty($list)) {
6923
            $userSessionList = [];
6924
            foreach ($list as $data) {
6925
                $sessionInfo = [];
6926
                if (isset($data['SessionId'])) {
6927
                    $sessionInfo = api_get_session_info($data['SessionId']);
6928
                }
6929
6930
                if (isset($data['SessionName']) && empty($sessionInfo)) {
6931
                $sessionInfo = self::get_session_by_name($data['SessionName']);
6932
                }
6933
6934
                if (empty($sessionInfo)) {
6935
                    $sessionData = isset($data['SessionName']) ? $data['SessionName'] : $data['SessionId'];
6936
                    Display::addFlash(
6937
                        Display::return_message(get_lang('SessionNotFound').' - '.$sessionData, 'warning')
6938
                    );
6939
                    continue;
6940
                }
6941
                $userList = explode(',', $data['Username']);
6942
6943
                foreach ($userList as $username) {
6944
                    $userInfo = api_get_user_info_from_username($username);
6945
6946
                if (empty($userInfo)) {
6947
                        Display::addFlash(
6948
                            Display::return_message(get_lang('UserDoesNotExist').' - '.$username, 'warning')
6949
                        );
6950
                        continue;
6951
                }
6952
6953
                if (!empty($userInfo) && !empty($sessionInfo)) {
6954
                    $userSessionList[$userInfo['user_id']]['session_list'][] = [
6955
                        'session_id' => $sessionInfo['id'],
6956
                        'session_info' => $sessionInfo,
6957
                    ];
6958
                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6959
                    }
6960
                }
6961
            }
6962
6963
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6964
6965
            return self::checkSubscribeDrhToSessionList($userSessionList);
6966
        }
6967
    }
6968
6969
    /**
6970
     * Courses re-ordering in resume_session.php flag see BT#8316.
6971
     */
6972
    public static function orderCourseIsEnabled()
6973
    {
6974
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6975
        if ('true' === $sessionCourseOrder) {
6976
            return true;
6977
        }
6978
6979
        return false;
6980
    }
6981
6982
    /**
6983
     * @param string $direction (up/down)
6984
     * @param int    $sessionId
6985
     * @param int    $courseId
6986
     *
6987
     * @return bool
6988
     */
6989
    public static function move($direction, $sessionId, $courseId)
6990
    {
6991
        if (!self::orderCourseIsEnabled()) {
6992
            return false;
6993
        }
6994
6995
        $sessionId = intval($sessionId);
6996
        $courseId = intval($courseId);
6997
6998
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6999
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
7000
7001
        $position = [];
7002
        $count = 0;
7003
        foreach ($courseList as $course) {
7004
            if ('' == $course['position']) {
7005
                $course['position'] = $count;
7006
            }
7007
            $position[$course['code']] = $course['position'];
7008
            // Saving current order.
7009
            $sql = "UPDATE $table SET position = $count
7010
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
7011
            Database::query($sql);
7012
            $count++;
7013
        }
7014
7015
        // Loading new positions.
7016
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
7017
7018
        $found = false;
7019
7020
        switch ($direction) {
7021
            case 'up':
7022
                $courseList = array_reverse($courseList);
7023
                break;
7024
            case 'down':
7025
                break;
7026
        }
7027
7028
        foreach ($courseList as $course) {
7029
            if ($found) {
7030
                $nextId = $course['real_id'];
7031
                $nextOrder = $course['position'];
7032
                break;
7033
            }
7034
7035
            if ($courseId == $course['real_id']) {
7036
                $thisCourseCode = $course['real_id'];
7037
                $thisOrder = $course['position'];
7038
                $found = true;
7039
            }
7040
        }
7041
7042
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
7043
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
7044
        Database::query($sql1);
7045
7046
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
7047
                 WHERE session_id = $sessionId AND c_id = $nextId";
7048
        Database::query($sql2);
7049
7050
        return true;
7051
    }
7052
7053
    /**
7054
     * @param int $sessionId
7055
     * @param int $courseId
7056
     *
7057
     * @return bool
7058
     */
7059
    public static function moveUp($sessionId, $courseId)
7060
    {
7061
        return self::move('up', $sessionId, $courseId);
7062
    }
7063
7064
    /**
7065
     * @param int    $sessionId
7066
     * @param string $courseCode
7067
     *
7068
     * @return bool
7069
     */
7070
    public static function moveDown($sessionId, $courseCode)
7071
    {
7072
        return self::move('down', $sessionId, $courseCode);
7073
    }
7074
7075
    /**
7076
     * Use the session duration to allow/block user access see BT#8317
7077
     * Needs these DB changes
7078
     * ALTER TABLE session ADD COLUMN duration int;
7079
     * ALTER TABLE session_rel_user ADD COLUMN duration int;.
7080
     */
7081
    public static function durationPerUserIsEnabled()
7082
    {
7083
        return api_get_configuration_value('session_duration_feature');
7084
    }
7085
7086
    /**
7087
     * Returns the number of days the student has left in a session when using
7088
     * sessions durations.
7089
     *
7090
     * @param int $userId
7091
     *
7092
     * @return int
7093
     */
7094
    public static function getDayLeftInSession(array $sessionInfo, $userId)
7095
    {
7096
        $sessionId = $sessionInfo['id'];
7097
        $subscription = self::getUserSession($userId, $sessionId);
7098
        $duration = empty($subscription['duration'])
7099
            ? $sessionInfo['duration']
7100
            : $sessionInfo['duration'] + $subscription['duration'];
7101
7102
        // Get an array with the details of the first access of the student to
7103
        // this session
7104
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
7105
            $sessionId,
7106
            $userId
7107
        );
7108
7109
        $currentTime = time();
7110
7111
        // If no previous access, return false
7112
        if (0 == count($courseAccess)) {
7113
            return $duration;
7114
        }
7115
7116
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
7117
        $endDateInSeconds = $firstAccess + $duration * 24 * 60 * 60;
7118
        $leftDays = round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
7119
7120
        return $leftDays;
7121
    }
7122
7123
    /**
7124
     * @param int $duration
7125
     * @param int $userId
7126
     * @param int $sessionId
7127
     *
7128
     * @return bool
7129
     */
7130
    public static function editUserSessionDuration($duration, $userId, $sessionId)
7131
    {
7132
        $duration = (int) $duration;
7133
        $userId = (int) $userId;
7134
        $sessionId = (int) $sessionId;
7135
7136
        if (empty($userId) || empty($sessionId)) {
7137
            return false;
7138
        }
7139
7140
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7141
        $parameters = ['duration' => $duration];
7142
        $where = ['session_id = ? AND user_id = ? ' => [$sessionId, $userId]];
7143
        Database::update($table, $parameters, $where);
7144
7145
        return true;
7146
    }
7147
7148
    /**
7149
     * Gets one row from the session_rel_user table.
7150
     *
7151
     * @param int $userId
7152
     * @param int $sessionId
7153
     *
7154
     * @return array
7155
     */
7156
    public static function getUserSession($userId, $sessionId)
7157
    {
7158
        $userId = (int) $userId;
7159
        $sessionId = (int) $sessionId;
7160
7161
        if (empty($userId) || empty($sessionId)) {
7162
            return false;
7163
        }
7164
7165
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7166
        $sql = "SELECT * FROM $table
7167
                WHERE session_id = $sessionId AND user_id = $userId";
7168
        $result = Database::query($sql);
7169
        $values = [];
7170
        if (Database::num_rows($result)) {
7171
            $values = Database::fetch_assoc($result);
7172
        }
7173
7174
        return $values;
7175
    }
7176
7177
    /**
7178
     * Check if user is subscribed inside a session as student.
7179
     *
7180
     * @param int $sessionId The session id
7181
     * @param int $userId    The user id
7182
     *
7183
     * @return bool Whether is subscribed
7184
     */
7185
    public static function isUserSubscribedAsStudent($sessionId, $userId)
7186
    {
7187
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7188
        $sessionId = (int) $sessionId;
7189
        $userId = (int) $userId;
7190
7191
        // COUNT(1) actually returns the number of rows from the table (as if
7192
        // counting the results from the first column)
7193
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7194
                WHERE
7195
                    session_id = $sessionId AND
7196
                    user_id = $userId AND
7197
                    relation_type = ".Session::STUDENT;
7198
7199
        $result = Database::fetch_assoc(Database::query($sql));
7200
7201
        if (!empty($result) && $result['qty'] > 0) {
7202
            return true;
7203
        }
7204
7205
        return false;
7206
    }
7207
7208
    /**
7209
     * Check if user is subscribed inside a session as a HRM.
7210
     *
7211
     * @param int $sessionId The session id
7212
     * @param int $userId    The user id
7213
     *
7214
     * @return bool Whether is subscribed
7215
     */
7216
    public static function isUserSubscribedAsHRM($sessionId, $userId)
7217
    {
7218
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7219
7220
        $sessionId = (int) $sessionId;
7221
        $userId = (int) $userId;
7222
7223
        // COUNT(1) actually returns the number of rows from the table (as if
7224
        // counting the results from the first column)
7225
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7226
                WHERE
7227
                    session_id = $sessionId AND
7228
                    user_id = $userId AND
7229
                    relation_type = ".Session::DRH;
7230
7231
        $result = Database::fetch_assoc(Database::query($sql));
7232
7233
        if (!empty($result) && $result['qty'] > 0) {
7234
            return true;
7235
        }
7236
7237
        return false;
7238
    }
7239
7240
    /**
7241
     * Get the session coached by a user (general coach and course-session coach).
7242
     *
7243
     * @param int  $coachId                       The coach id
7244
     * @param bool $checkSessionRelUserVisibility Check the session visibility
7245
     * @param bool $asPlatformAdmin               The user is a platform admin and we want all sessions
7246
     *
7247
     * @return array The session list
7248
     */
7249
    public static function getSessionsCoachedByUser(
7250
        $coachId,
7251
        $checkSessionRelUserVisibility = false,
7252
        $asPlatformAdmin = false
7253
    ) {
7254
        // Get all sessions where $coachId is the general coach
7255
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
7256
        // Get all sessions where $coachId is the course - session coach
7257
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
7258
        $sessionsByCoach = [];
7259
        if (!empty($courseSessionList)) {
7260
            foreach ($courseSessionList as $userCourseSubscription) {
7261
                $session = $userCourseSubscription->getSession();
7262
                $sessionsByCoach[$session->getId()] = api_get_session_info(
7263
                    $session->getId()
7264
                );
7265
            }
7266
        }
7267
7268
        if (!empty($sessionsByCoach)) {
7269
            $sessions = array_merge($sessions, $sessionsByCoach);
7270
        }
7271
7272
        // Remove repeated sessions
7273
        if (!empty($sessions)) {
7274
            $cleanSessions = [];
7275
            foreach ($sessions as $session) {
7276
                $cleanSessions[$session['id']] = $session;
7277
            }
7278
            $sessions = $cleanSessions;
7279
        }
7280
7281
        if ($checkSessionRelUserVisibility) {
7282
            if (!empty($sessions)) {
7283
                $newSessions = [];
7284
                foreach ($sessions as $session) {
7285
                    $visibility = api_get_session_visibility($session['id']);
7286
                    if (SESSION_INVISIBLE == $visibility) {
7287
                        continue;
7288
                    }
7289
                    $newSessions[] = $session;
7290
                }
7291
                $sessions = $newSessions;
7292
            }
7293
        }
7294
7295
        return $sessions;
7296
    }
7297
7298
    /**
7299
     * Check if the course belongs to the session.
7300
     *
7301
     * @param int    $sessionId  The session id
7302
     * @param string $courseCode The course code
7303
     *
7304
     * @return bool
7305
     */
7306
    public static function sessionHasCourse($sessionId, $courseCode)
7307
    {
7308
        $sessionId = (int) $sessionId;
7309
        $courseCode = Database::escape_string($courseCode);
7310
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7311
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7312
7313
        $sql = "SELECT COUNT(1) AS qty
7314
                FROM $courseTable c
7315
                INNER JOIN $sessionRelCourseTable src
7316
                ON c.id = src.c_id
7317
                WHERE src.session_id = $sessionId
7318
                AND c.code = '$courseCode'  ";
7319
7320
        $result = Database::query($sql);
7321
7322
        if (false !== $result) {
7323
            $data = Database::fetch_assoc($result);
7324
7325
            if ($data['qty'] > 0) {
7326
                return true;
7327
            }
7328
        }
7329
7330
        return false;
7331
    }
7332
7333
    /**
7334
     * Calculate the total user time in the platform.
7335
     *
7336
     * @param int    $userId The user id
7337
     * @param string $from   Optional. From date
7338
     * @param string $until  Optional. Until date
7339
     *
7340
     * @return string The time (hh:mm:ss)
7341
     */
7342
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
7343
    {
7344
        $userId = (int) $userId;
7345
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
7346
        $whereConditions = [
7347
            'login_user_id = ? ' => $userId,
7348
        ];
7349
7350
        if (!empty($from) && !empty($until)) {
7351
            $whereConditions["AND (login_date >= '?' "] = $from;
7352
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
7353
        }
7354
7355
        $trackResult = Database::select(
7356
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
7357
            $trackLoginTable,
7358
            [
7359
                'where' => $whereConditions,
7360
            ],
7361
            'first'
7362
        );
7363
7364
        if (false != $trackResult) {
7365
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
7366
        }
7367
7368
        return '00:00:00';
7369
    }
7370
7371
    /**
7372
     * Get the courses list by a course coach.
7373
     *
7374
     * @param int $coachId The coach id
7375
     *
7376
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
7377
     */
7378
    public static function getCoursesListByCourseCoach($coachId)
7379
    {
7380
        $entityManager = Database::getManager();
7381
        $repo = $entityManager->getRepository(SessionRelCourseRelUser::class);
7382
7383
        return $repo->findBy([
7384
            'user' => $coachId,
7385
            'status' => Session::COURSE_COACH,
7386
        ]);
7387
    }
7388
7389
    /**
7390
     * Get the count of user courses in session.
7391
     *
7392
     * @param int $sessionId
7393
     * @param int $courseId
7394
     *
7395
     * @return array
7396
     */
7397
    public static function getTotalUserCoursesInSession($sessionId, $courseId = 0)
7398
    {
7399
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
7400
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7401
7402
        $sessionId = (int) $sessionId;
7403
7404
        if (empty($sessionId)) {
7405
            return [];
7406
        }
7407
7408
        $courseCondition = '';
7409
        if (!empty($courseId)) {
7410
            $courseId = (int) $courseId;
7411
            $courseCondition = "  c_id = $courseId AND ";
7412
        }
7413
7414
        $sql = "SELECT
7415
                    COUNT(u.id) as count,
7416
                    u.id,
7417
                    scu.status status_in_session,
7418
                    u.status user_status
7419
                FROM $table scu
7420
                INNER JOIN $tableUser u
7421
                ON scu.user_id = u.id
7422
                WHERE
7423
                  $courseCondition
7424
                  scu.session_id = ".$sessionId."
7425
                GROUP BY u.id";
7426
7427
        $result = Database::query($sql);
7428
7429
        $list = [];
7430
        while ($data = Database::fetch_assoc($result)) {
7431
            $list[] = $data;
7432
        }
7433
7434
        return $list;
7435
    }
7436
7437
    /**
7438
     * Returns list of a few data from session (name, short description, start
7439
     * date, end date) and the given extra fields if defined based on a
7440
     * session category Id.
7441
     *
7442
     * @param int    $categoryId  The internal ID of the session category
7443
     * @param string $target      Value to search for in the session field values
7444
     * @param array  $extraFields A list of fields to be scanned and returned
7445
     *
7446
     * @return mixed
7447
     */
7448
    public static function getShortSessionListAndExtraByCategory(
7449
        $categoryId,
7450
        $target,
7451
        $extraFields = null,
7452
        $publicationDate = null
7453
    ) {
7454
        $categoryId = (int) $categoryId;
7455
        $sessionList = [];
7456
        // Check if categoryId is valid
7457
        if ($categoryId > 0) {
7458
            $target = Database::escape_string($target);
7459
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7460
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7461
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7462
            // Join session field and session field values tables
7463
            $joinTable = $sfTable.' sf INNER JOIN '.$sfvTable.' sfv ON sf.id = sfv.field_id';
7464
            $fieldsArray = [];
7465
            foreach ($extraFields as $field) {
7466
                $fieldsArray[] = Database::escape_string($field);
7467
            }
7468
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7469
            if (isset($publicationDate)) {
7470
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
7471
                $wherePublication = " AND id NOT IN (
7472
                    SELECT sfv.item_id FROM $joinTable
7473
                    WHERE
7474
                        sf.item_type = $extraFieldType AND
7475
                        ((sf.variable = 'publication_start_date' AND sfv.field_value > '$publicationDateString' and sfv.field_value != '') OR
7476
                        (sf.variable = 'publication_end_date' AND sfv.field_value < '$publicationDateString' and sfv.field_value != ''))
7477
                )";
7478
            }
7479
            // Get the session list from session category and target
7480
            $sessionList = Database::select(
7481
                'id, title, access_start_date, access_end_date',
7482
                $sTable,
7483
                [
7484
                    'where' => [
7485
                        "session_category_id = ? AND id IN (
7486
                            SELECT sfv.item_id FROM $joinTable
7487
                            WHERE
7488
                                sf.item_type = $extraFieldType AND
7489
                                sfv.item_id = session.id AND
7490
                                sf.variable = 'target' AND
7491
                                sfv.field_value = ?
7492
                        ) $wherePublication" => [$categoryId, $target],
7493
                    ],
7494
                ]
7495
            );
7496
            $whereFieldVariables = [];
7497
            $whereFieldIds = [];
7498
            if (
7499
                is_array($fieldsArray) &&
7500
                count($fieldsArray) > 0
7501
            ) {
7502
                $whereParams = '?';
7503
                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...
7504
                    $whereParams .= ', ?';
7505
                }
7506
                $whereFieldVariables = ' variable IN ( '.$whereParams.' )';
7507
                $whereFieldIds = 'field_id IN ( '.$whereParams.' )';
7508
            }
7509
            // Get session fields
7510
            $extraField = new ExtraFieldModel('session');
7511
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
7512
            $fieldsList = $extraField->get_all([
7513
                ' variable IN ( '.$questionMarks.' )' => $fieldsArray,
7514
            ]);
7515
            // Index session fields
7516
            foreach ($fieldsList as $field) {
7517
                $fields[$field['id']] = $field['variable'];
7518
            }
7519
            // Get session field values
7520
            $extra = new ExtraFieldValue('session');
7521
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
7522
            $sessionFieldValueList = $extra->get_all(['where' => ['field_id IN ( '.$questionMarksFields.' )' => array_keys($fields)]]);
7523
            // Add session fields values to session list
7524
            foreach ($sessionList as $id => &$session) {
7525
                foreach ($sessionFieldValueList as $sessionFieldValue) {
7526
                    // Match session field values to session
7527
                    if ($sessionFieldValue['item_id'] == $id) {
7528
                        // Check if session field value is set in session field list
7529
                        if (isset($fields[$sessionFieldValue['field_id']])) {
7530
                            // Avoid overwriting the session's ID field
7531
                            if ('id' != $fields[$sessionFieldValue['field_id']]) {
7532
                                $var = $fields[$sessionFieldValue['field_id']];
7533
                                $val = $sessionFieldValue['value'];
7534
                                // Assign session field value to session
7535
                                $session[$var] = $val;
7536
                            }
7537
                        }
7538
                    }
7539
                }
7540
            }
7541
        }
7542
7543
        return $sessionList;
7544
    }
7545
7546
    /**
7547
     * Return the Session Category id searched by name.
7548
     *
7549
     * @param string $categoryName Name attribute of session category used for search query
7550
     * @param bool   $force        boolean used to get even if something is wrong (e.g not unique name)
7551
     *
7552
     * @return int|array If success, return category id (int), else it will return an array
7553
     *                   with the next structure:
7554
     *                   array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7555
     */
7556
    public static function getSessionCategoryIdByName($categoryName, $force = false)
7557
    {
7558
        // Start error result
7559
        $errorResult = ['error' => true, 'errorMessage' => get_lang('There was an error.')];
7560
        $categoryName = Database::escape_string($categoryName);
7561
        // Check if is not empty category name
7562
        if (!empty($categoryName)) {
7563
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7564
            // Get all session category with same name
7565
            $result = Database::select(
7566
                'id',
7567
                $sessionCategoryTable,
7568
                [
7569
                    'where' => [
7570
                        'title = ?' => $categoryName,
7571
                    ],
7572
                ]
7573
            );
7574
            // Check the result
7575
            if ($result < 1) {
7576
                // If not found any result, update error message
7577
                $errorResult['errorMessage'] = 'Not found any session category name '.$categoryName;
7578
            } elseif (count($result) > 1 && !$force) {
7579
                // If found more than one result and force is disabled, update error message
7580
                $errorResult['errorMessage'] = 'Found many session categories';
7581
            } elseif (1 == count($result) || $force) {
7582
                // If found just one session category or force option is enabled
7583
7584
                return key($result);
7585
            }
7586
        } else {
7587
            // category name is empty, update error message
7588
            $errorResult['errorMessage'] = 'Not valid category name';
7589
        }
7590
7591
        return $errorResult;
7592
    }
7593
7594
    /**
7595
     * Return all data from sessions (plus extra field, course and coach data) by category id.
7596
     *
7597
     * @param int $sessionCategoryId session category id used to search sessions
7598
     *
7599
     * @return array If success, return session list and more session related data, else it will return an array
7600
     *               with the next structure:
7601
     *               array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7602
     */
7603
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
7604
    {
7605
        // Start error result
7606
        $errorResult = [
7607
            'error' => true,
7608
            'errorMessage' => get_lang('There was an error.'),
7609
        ];
7610
7611
        $sessionCategoryId = intval($sessionCategoryId);
7612
        // Check if session category id is valid
7613
        if ($sessionCategoryId > 0) {
7614
            // Get table names
7615
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7616
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7617
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7618
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7619
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
7620
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7621
7622
            // Get all data from all sessions whit the session category specified
7623
            $sessionList = Database::select(
7624
                '*',
7625
                $sessionTable,
7626
                [
7627
                    'where' => [
7628
                        'session_category_id = ?' => $sessionCategoryId,
7629
                    ],
7630
                ]
7631
            );
7632
7633
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7634
7635
            // Check if session list query had result
7636
            if (!empty($sessionList)) {
7637
                // implode all session id
7638
                $sessionIdsString = '('.implode(', ', array_keys($sessionList)).')';
7639
                // Get all field variables
7640
                $sessionFieldList = Database::select(
7641
                    'id, variable',
7642
                    $sessionFieldTable,
7643
                    ['item_type = ? ' => [$extraFieldType]]
7644
                );
7645
7646
                // Get all field values
7647
                $sql = "SELECT item_id, field_id, value FROM
7648
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
7649
                        ON (f.id = v.field_id)
7650
                        WHERE
7651
                            item_id IN $sessionIdsString AND
7652
                            item_type = $extraFieldType
7653
                ";
7654
                $result = Database::query($sql);
7655
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
7656
7657
                // Check if session field values had result
7658
                if (!empty($sessionFieldValueList)) {
7659
                    $sessionFieldValueListBySession = [];
7660
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
7661
                        // Create an array to index ids to session id
7662
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
7663
                    }
7664
                }
7665
                // Query used to find course-coaches from sessions
7666
                $sql = "SELECT
7667
                            scu.session_id,
7668
                            c.id AS course_id,
7669
                            c.code AS course_code,
7670
                            c.title AS course_title,
7671
                            u.username AS coach_username,
7672
                            u.firstname AS coach_firstname,
7673
                            u.lastname AS coach_lastname
7674
                        FROM $courseTable c
7675
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
7676
                        INNER JOIN $userTable u ON scu.user_id = u.id
7677
                        WHERE scu.status = ".Session::COURSE_COACH." AND scu.session_id IN $sessionIdsString
7678
                        ORDER BY scu.session_id ASC ";
7679
                $res = Database::query($sql);
7680
                $sessionCourseList = Database::store_result($res, 'ASSOC');
7681
                // Check if course list had result
7682
                if (!empty($sessionCourseList)) {
7683
                    foreach ($sessionCourseList as $key => $sessionCourse) {
7684
                        // Create an array to index ids to session_id
7685
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
7686
                    }
7687
                }
7688
                // Join lists
7689
                if (is_array($sessionList)) {
7690
                    foreach ($sessionList as $id => &$row) {
7691
                        if (
7692
                            !empty($sessionFieldValueListBySession) &&
7693
                            is_array($sessionFieldValueListBySession[$id])
7694
                        ) {
7695
                            // If have an index array for session extra fields, use it to join arrays
7696
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
7697
                                $row['extra'][$key] = [
7698
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
7699
                                    'value' => $sessionFieldValueList[$key]['value'],
7700
                                ];
7701
                            }
7702
                        }
7703
                        if (
7704
                            !empty($sessionCourseListBySession) &&
7705
                            is_array($sessionCourseListBySession[$id])
7706
                        ) {
7707
                            // If have an index array for session course coach, use it to join arrays
7708
                            foreach ($sessionCourseListBySession[$id] as $key) {
7709
                                $row['course'][$key] = [
7710
                                    'course_id' => $sessionCourseList[$key]['course_id'],
7711
                                    'course_code' => $sessionCourseList[$key]['course_code'],
7712
                                    'course_title' => $sessionCourseList[$key]['course_title'],
7713
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
7714
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
7715
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
7716
                                ];
7717
                            }
7718
                        }
7719
                    }
7720
                }
7721
7722
                return $sessionList;
7723
            } else {
7724
                // Not found result, update error message
7725
                $errorResult['errorMessage'] = 'Not found any session for session category id '.$sessionCategoryId;
7726
            }
7727
        }
7728
7729
        return $errorResult;
7730
    }
7731
7732
    /**
7733
     * Return session description from session id.
7734
     *
7735
     * @param int $sessionId
7736
     *
7737
     * @return string
7738
     */
7739
    public static function getDescriptionFromSessionId($sessionId)
7740
    {
7741
        // Init variables
7742
        $sessionId = (int) $sessionId;
7743
        $description = '';
7744
        // Check if session id is valid
7745
        if ($sessionId > 0) {
7746
            // Select query from session id
7747
            $rows = Database::select(
7748
                'description',
7749
                Database::get_main_table(TABLE_MAIN_SESSION),
7750
                [
7751
                    'where' => [
7752
                        'id = ?' => $sessionId,
7753
                    ],
7754
                ]
7755
            );
7756
7757
            // Check if select query result is not empty
7758
            if (!empty($rows)) {
7759
                // Get session description
7760
                $description = $rows[0]['description'];
7761
            }
7762
        }
7763
7764
        return $description;
7765
    }
7766
7767
    /**
7768
     * Get a session list filtered by name, description or any of the given extra fields.
7769
     *
7770
     * @param string $term                 The term to search
7771
     * @param array  $extraFieldsToInclude Extra fields to include in the session data
7772
     *
7773
     * @return array The list
7774
     */
7775
    public static function searchSession($term, $extraFieldsToInclude = [])
7776
    {
7777
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7778
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7779
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7780
        $term = Database::escape_string($term);
7781
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7782
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
7783
            $resultData = Database::select('*', $sTable, [
7784
                'where' => [
7785
                    "title LIKE %?% " => $term,
7786
                    " OR description LIKE %?% " => $term,
7787
                    " OR id IN (
7788
                    SELECT item_id
7789
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
7790
                    ON (v.field_id = e.id)
7791
                    WHERE field_value LIKE %?% AND item_type = $extraFieldType
7792
                ) " => $term,
7793
                ],
7794
            ]);
7795
        } else {
7796
            $resultData = Database::select('*', $sTable, [
7797
                'where' => [
7798
                    "title LIKE %?% " => $term,
7799
                    "OR description LIKE %?% " => $term,
7800
                ],
7801
            ]);
7802
7803
            return $resultData;
7804
        }
7805
7806
        foreach ($resultData as $id => &$session) {
7807
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
7808
        }
7809
7810
        return $resultData;
7811
    }
7812
7813
    /**
7814
     * @param int   $sessionId
7815
     * @param array $extraFieldsToInclude (empty means all)
7816
     *
7817
     * @return array
7818
     */
7819
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = [])
7820
    {
7821
        $extraData = [];
7822
        $variables = [];
7823
        $variablePlaceHolders = [];
7824
7825
        foreach ($extraFieldsToInclude as $sessionExtraField) {
7826
            $variablePlaceHolders[] = "?";
7827
            $variables[] = Database::escape_string($sessionExtraField);
7828
        }
7829
7830
        $sessionExtraField = new ExtraFieldModel('session');
7831
        $fieldList = $sessionExtraField->get_all(empty($extraFieldsToInclude) ? [] : [
7832
            "variable IN ( ".implode(", ", $variablePlaceHolders)." ) " => $variables,
7833
        ]);
7834
7835
        if (empty($fieldList)) {
7836
            return [];
7837
        }
7838
7839
        $fields = [];
7840
7841
        // Index session fields
7842
        foreach ($fieldList as $field) {
7843
            $fields[$field['id']] = $field['variable'];
7844
        }
7845
7846
        // Get session field values
7847
        $extra = new ExtraFieldValue('session');
7848
        $sessionFieldValueList = [];
7849
        foreach (array_keys($fields) as $fieldId) {
7850
            $sessionFieldValue = $extra->get_values_by_handler_and_field_id($sessionId, $fieldId);
7851
            if (false != $sessionFieldValue) {
7852
                $sessionFieldValueList[$fieldId] = $sessionFieldValue;
7853
            }
7854
        }
7855
7856
        foreach ($sessionFieldValueList as $sessionFieldValue) {
7857
            // Match session field values to session
7858
            if ($sessionFieldValue['item_id'] != $sessionId) {
7859
                continue;
7860
            }
7861
7862
            // Check if session field value is set in session field list
7863
            if (!isset($fields[$sessionFieldValue['field_id']])) {
7864
                continue;
7865
            }
7866
7867
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
7868
            $extrafieldValue = $sessionFieldValue['value'];
7869
7870
            $extraData[] = [
7871
                'variable' => $extrafieldVariable,
7872
                'value' => $extrafieldValue,
7873
            ];
7874
        }
7875
7876
        return $extraData;
7877
    }
7878
7879
    /**
7880
     * @param int $sessionId
7881
     *
7882
     * @return bool
7883
     */
7884
    public static function isValidId($sessionId)
7885
    {
7886
        $sessionId = (int) $sessionId;
7887
        if ($sessionId > 0) {
7888
            $rows = Database::select(
7889
                'id',
7890
                Database::get_main_table(TABLE_MAIN_SESSION),
7891
                ['where' => ['id = ?' => $sessionId]]
7892
            );
7893
            if (!empty($rows)) {
7894
                return true;
7895
            }
7896
        }
7897
7898
        return false;
7899
    }
7900
7901
    /**
7902
     * Get list of sessions based on users of a group for a group admin.
7903
     *
7904
     * @param int $userId The user id
7905
     *
7906
     * @return array
7907
     */
7908
    public static function getSessionsFollowedForGroupAdmin($userId)
7909
    {
7910
        $sessionList = [];
7911
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7912
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7913
        $userGroup = new UserGroupModel();
7914
        $userIdList = $userGroup->getGroupUsersByUser($userId);
7915
7916
        if (empty($userIdList)) {
7917
            return [];
7918
        }
7919
7920
        $sql = "SELECT DISTINCT s.*
7921
                FROM $sessionTable s
7922
                INNER JOIN $sessionUserTable sru
7923
                ON s.id = sru.id_session
7924
                WHERE
7925
                    (sru.id_user IN (".implode(', ', $userIdList).")
7926
                    AND sru.relation_type = ".Session::STUDENT."
7927
                )";
7928
7929
        if (api_is_multiple_url_enabled()) {
7930
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7931
            $accessUrlId = api_get_current_access_url_id();
7932
7933
            if (-1 != $accessUrlId) {
7934
                $sql = "SELECT DISTINCT s.*
7935
                        FROM $sessionTable s
7936
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
7937
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
7938
                        WHERE
7939
                            srau.access_url_id = $accessUrlId
7940
                            AND (
7941
                                sru.id_user IN (".implode(', ', $userIdList).")
7942
                                AND sru.relation_type = ".Session::STUDENT."
7943
                            )";
7944
            }
7945
        }
7946
7947
        $result = Database::query($sql);
7948
        while ($row = Database::fetch_assoc($result)) {
7949
            $sessionList[] = $row;
7950
        }
7951
7952
        return $sessionList;
7953
    }
7954
7955
    public static function getSessionVisibility(Session $session) : string
7956
    {
7957
        switch ($session->getVisibility()) {
7958
            case 1:
7959
                return get_lang('Read only');
7960
            case 2:
7961
                return get_lang('Visible');
7962
            case 3:
7963
                return api_ucfirst(get_lang('invisible'));
7964
        }
7965
7966
        return '';
7967
    }
7968
7969
    /**
7970
     * Returns a human readable string.
7971
     *
7972
     * @return array
7973
     */
7974
    public static function parseSessionDates(Session $session, bool $showTime = false)
7975
    {
7976
        $displayDates = self::convertSessionDateToString(
7977
            $session->getDisplayStartDate(),
7978
            $session->getDisplayEndDate(),
7979
            $showTime,
7980
            true
7981
        );
7982
        $accessDates = self::convertSessionDateToString(
7983
            $session->getAccessStartDate(),
7984
            $session->getAccessEndDate(),
7985
            $showTime,
7986
            true
7987
        );
7988
7989
        $coachDates = self::convertSessionDateToString(
7990
            $session->getCoachAccessStartDate(),
7991
            $session->getCoachAccessEndDate(),
7992
            $showTime,
7993
            true
7994
        );
7995
7996
        return [
7997
            'access' => $accessDates,
7998
            'display' => $displayDates,
7999
            'coach' => $coachDates,
8000
        ];
8001
    }
8002
8003
    /**
8004
     * @throws Exception
8005
     */
8006
    public static function setForm(FormValidator $form, Session $session = null, $fromSessionId = null): array
8007
    {
8008
        $categoriesList = self::get_all_session_category();
8009
8010
        $categoriesOptions = [
8011
            '0' => get_lang('none'),
8012
        ];
8013
8014
        if (false != $categoriesList) {
8015
            foreach ($categoriesList as $categoryItem) {
8016
                $categoriesOptions[$categoryItem['id']] = $categoryItem['title'];
8017
            }
8018
        }
8019
8020
        // Database Table Definitions
8021
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8022
8023
        $form->addText(
8024
            'title',
8025
            get_lang('Session name'),
8026
            true,
8027
            ['maxlength' => 150, 'aria-label' => get_lang('Session name')]
8028
        );
8029
        $form->addRule('title', get_lang('Session name already exists'), 'callback', 'check_session_name');
8030
8031
        if (!api_is_platform_admin() && api_is_teacher()) {
8032
            $form->addSelectFromCollection(
8033
                'coach_username',
8034
                get_lang('Coach name'),
8035
                [api_get_user_entity()],
8036
                [
8037
                    'id' => 'coach_username',
8038
                    'style' => 'width:370px;',
8039
                    'multiple' => true,
8040
                ],
8041
                false,
8042
                'getFullname'
8043
            );
8044
        } else {
8045
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE active <> ".USER_SOFT_DELETED." AND status = 1";
8046
            $rs = Database::query($sql);
8047
            $countUsers = (int) Database::result($rs, 0, '0');
8048
8049
            if ($countUsers < 1) {
8050
                $orderClause = 'ORDER BY ';
8051
                $orderClause .= api_sort_by_first_name() ? 'firstname, lastname, username' : 'lastname, firstname, username';
8052
8053
                $sql = "SELECT id as user_id, lastname, firstname, username
8054
                        FROM $tbl_user
8055
                        WHERE active <> -1 AND status = '1' ".
8056
                        $orderClause;
8057
8058
                if (api_is_multiple_url_enabled()) {
8059
                    $userRelAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
8060
                    $accessUrlId = api_get_current_access_url_id();
8061
                    if (-1 != $accessUrlId) {
8062
                        $sql = "SELECT user.id as user_id, username, lastname, firstname
8063
                        FROM $tbl_user user
8064
                        INNER JOIN $userRelAccessUrlTable url_user
8065
                        ON (url_user.user_id = user.id)
8066
                        WHERE
8067
                            user.active <> -1 AND
8068
                            access_url_id = $accessUrlId AND
8069
                            status = 1 "
8070
                            .$orderClause;
8071
                    }
8072
                }
8073
8074
                $result = Database::query($sql);
8075
                $coachesList = Database::store_result($result);
8076
                $coachesOptions = [];
8077
                foreach ($coachesList as $coachItem) {
8078
                    $coachesOptions[$coachItem['user_id']] =
8079
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
8080
                }
8081
8082
                $form->addSelect(
8083
                    'coach_username',
8084
                    get_lang('Coach name'),
8085
                    $coachesOptions,
8086
                    [
8087
                        'id' => 'coach_username',
8088
                        'style' => 'width:370px;',
8089
                        'multiple' => true,
8090
                    ]
8091
                );
8092
            } else {
8093
                $coaches = [];
8094
8095
                if ($session) {
8096
                    foreach ($session->getGeneralCoaches() as $coach) {
8097
                        $coaches[$coach->getId()] = $coach->getFullName();
8098
                    }
8099
                }
8100
8101
                $form->addSelectAjax(
8102
                    'coach_username',
8103
                    get_lang('Coach name'),
8104
                    $coaches,
8105
                    [
8106
                        'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_general_coach',
8107
                        'width' => '100%',
8108
                        'id' => 'coach_username',
8109
                        'multiple' => true,
8110
                    ]
8111
                );
8112
            }
8113
        }
8114
8115
        $form->addRule('coach_username', get_lang('Required field'), 'required');
8116
        $form->addHtml('<div id="ajax_list_coachs"></div>');
8117
8118
        $form->addButtonAdvancedSettings('advanced_params');
8119
        $form->addElement('html', '<div id="advanced_params_options" style="'.(isset($fromSessionId) ? 'display:block' : 'display:none').'">');
8120
8121
        if (null === $session) {
8122
            $form->addSelectAjax(
8123
                'session_template',
8124
                get_lang('Session template'),
8125
                [],
8126
                [
8127
                    'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_template_session',
8128
                    'id' => 'system_template',
8129
                ]
8130
            );
8131
        }
8132
8133
        if (isset($fromSessionId)) {
8134
            $session = api_get_session_entity($fromSessionId);
8135
        }
8136
        $form->addSelect(
8137
            'session_category',
8138
            get_lang('Sessions categories'),
8139
            $categoriesOptions,
8140
            [
8141
                'id' => 'session_category',
8142
            ]
8143
        );
8144
8145
        $statusList = self::getStatusList();
8146
        $form->addSelect(
8147
            'status',
8148
            get_lang('Session status'),
8149
            $statusList,
8150
            [
8151
                'id' => 'status',
8152
            ]
8153
        );
8154
8155
        $form->addHtmlEditor(
8156
            'description',
8157
            get_lang('Description'),
8158
            false,
8159
            false,
8160
            [
8161
                'ToolbarSet' => 'Minimal',
8162
            ]
8163
        );
8164
8165
        $form->addElement('checkbox', 'show_description', null, get_lang('Show description'));
8166
8167
        $visibilityGroup = [];
8168
        $visibilityGroup[] = $form->createElement(
8169
            'select',
8170
            'session_visibility',
8171
            null,
8172
            [
8173
                SESSION_VISIBLE_READ_ONLY => get_lang('Read only'),
8174
                SESSION_VISIBLE => get_lang('Accessible'),
8175
                SESSION_INVISIBLE => api_ucfirst(get_lang('Not accessible')),
8176
            ],
8177
            []
8178
        );
8179
        $form->addGroup(
8180
            $visibilityGroup,
8181
            'visibility_group',
8182
            get_lang('Visibility after end date'),
8183
            null,
8184
            false
8185
        );
8186
8187
        $options = [
8188
            0 => get_lang('By duration'),
8189
            1 => get_lang('By dates'),
8190
        ];
8191
8192
        $form->addSelect('access', get_lang('Access'), $options, [
8193
            'onchange' => 'accessSwitcher(this.value)',
8194
            'id' => 'access',
8195
        ]);
8196
8197
        $form->addHtml('<div id="duration_div" style="display:none">');
8198
        $form->addElement(
8199
            'number',
8200
            'duration',
8201
            [
8202
                get_lang('Session duration'),
8203
                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.'),
8204
            ],
8205
            [
8206
                'maxlength' => 50,
8207
            ]
8208
        );
8209
8210
        $form->addHtml('</div>');
8211
        $form->addHtml('<div id="date_fields" style="display:none">');
8212
8213
        // Dates
8214
        $form->addDateTimePicker(
8215
            'access_start_date',
8216
            [get_lang('Access start date'), get_lang('Date on which the session is made available to all')],
8217
            ['id' => 'access_start_date']
8218
        );
8219
8220
        $form->addDateTimePicker(
8221
            'access_end_date',
8222
            [get_lang('Access end date'), get_lang('Date on which the session is closed')],
8223
            ['id' => 'access_end_date']
8224
        );
8225
8226
        $form->addRule(
8227
            ['access_start_date', 'access_end_date'],
8228
            get_lang('Start date must be before the end date'),
8229
            'compare_datetime_text',
8230
            '< allow_empty'
8231
        );
8232
8233
        $form->addDateTimePicker(
8234
            'display_start_date',
8235
            [
8236
                get_lang('Start date to display'),
8237
                get_lang('Date that will be shown in the session information as the date on which the session starts'),
8238
            ],
8239
            ['id' => 'display_start_date']
8240
        );
8241
8242
        $form->addDateTimePicker(
8243
            'display_end_date',
8244
            [
8245
                get_lang('End date to display'),
8246
                get_lang('Date that will be shown in the session information as the date on which the session ends'),
8247
            ],
8248
            ['id' => 'display_end_date']
8249
        );
8250
8251
        $form->addRule(
8252
            ['display_start_date', 'display_end_date'],
8253
            get_lang('Start date must be before the end date'),
8254
            'compare_datetime_text',
8255
            '< allow_empty'
8256
        );
8257
8258
        $form->addDateTimePicker(
8259
            'coach_access_start_date',
8260
            [
8261
                get_lang('Access start date for coaches'),
8262
                get_lang('Date on which the session is made available to coaches, so they can prepare it before the students get connected'),
8263
            ],
8264
            ['id' => 'coach_access_start_date']
8265
        );
8266
8267
        $form->addDateTimePicker(
8268
            'coach_access_end_date',
8269
            [
8270
                get_lang('Access end date for coaches'),
8271
                get_lang('Date on which the session is closed to coaches. The additional delay will allow them to export all relevant tracking information'),
8272
            ],
8273
            ['id' => 'coach_access_end_date']
8274
        );
8275
8276
        $form->addRule(
8277
            ['coach_access_start_date', 'coach_access_end_date'],
8278
            get_lang('Start date must be before the end date'),
8279
            'compare_datetime_text',
8280
            '< allow_empty'
8281
        );
8282
8283
        $form->addElement('html', '</div>');
8284
8285
        $form->addCheckBox(
8286
            'send_subscription_notification',
8287
            get_lang('Send an email when a user being subscribed to session'),
8288
        );
8289
8290
        $form->addCheckBox(
8291
            'notify_boss',
8292
            get_lang('Notify inscription of user to student boss')
8293
        );
8294
8295
        // Picture
8296
        $form->addFile(
8297
            'picture',
8298
            get_lang('Add image'),
8299
            ['id' => 'picture', 'class' => 'picture-form', 'crop_image' => true]
8300
        );
8301
        $allowedPictureTypes = api_get_supported_image_extensions(false);
8302
        $form->addRule('picture', get_lang('Only PNG, JPG or GIF images allowed').' ('.implode(',', $allowedPictureTypes).')', 'filetype', $allowedPictureTypes);
8303
8304
        if ($session && $session->getImage()) {
8305
            if (isset($fromSessionId)) {
8306
                $imageUrl = self::getSessionPictureUrl($session);
8307
                $form->addLabel(get_lang('Image'), "<img src = '$imageUrl' />");
8308
                $form->addHidden('image_session_template', $imageUrl);
8309
8310
            } else {
8311
                $form->addElement('checkbox', 'delete_picture', null, get_lang('Delete picture'));
8312
                $imageUrl = self::getSessionPictureUrl($session);
8313
                $form->addLabel(get_lang('Image'), "<img src = '$imageUrl' />");
8314
            }
8315
        }
8316
8317
        // Extra fields
8318
        $extra_field = new ExtraFieldModel('session');
8319
        $extra = $extra_field->addElements($form, $session ? $session->getId() : 0, ['image']);
8320
8321
        if ('true' === api_get_setting('session.enable_auto_reinscription')) {
8322
            $form->addElement(
8323
                'text',
8324
                'days_before_finishing_for_reinscription',
8325
                get_lang('Days before finishing for reinscription'),
8326
                ['maxlength' => 5]
8327
            );
8328
            $form->addRule(
8329
                'days_before_finishing_for_reinscription',
8330
                get_lang('Days must be a positive number or empty'),
8331
                'regex',
8332
                '/^\d*$/'
8333
            );
8334
        }
8335
8336
        if ('true' === api_get_setting('session.enable_session_replication')) {
8337
            $form->addElement(
8338
                'text',
8339
                'days_before_finishing_to_create_new_repetition',
8340
                get_lang('Days before finishing to create new repetition'),
8341
                ['maxlength' => 5]
8342
            );
8343
            $form->addRule(
8344
                'days_before_finishing_to_create_new_repetition',
8345
                get_lang('Days must be a positive number or empty'),
8346
                'regex',
8347
                '/^\d*$/'
8348
            );
8349
        }
8350
8351
        if ('true' === api_get_setting('session.enable_auto_reinscription') || 'true' === api_get_setting('session.enable_session_replication')) {
8352
            $form->addElement(
8353
                'checkbox',
8354
                'last_repetition',
8355
                get_lang('Last repetition')
8356
            );
8357
8358
            $form->addElement(
8359
                'number',
8360
                'validity_in_days',
8361
                get_lang('Validity in days'),
8362
                [
8363
                    'min' => 0,
8364
                    'max' => 365,
8365
                    'step' => 1,
8366
                    'placeholder' => get_lang('Enter the number of days'),
8367
                ]
8368
            );
8369
8370
            $form->addRule(
8371
                'validity_in_days',
8372
                get_lang('The field must be a positive number'),
8373
                'numeric',
8374
                null,
8375
                'client'
8376
            );
8377
        }
8378
8379
        /** @var HTML_QuickForm_select $element */
8380
        $element = $form->createElement(
8381
            'select',
8382
            'parent_id',
8383
            get_lang('Parent session'),
8384
            [],
8385
            ['class' => 'form-control']
8386
        );
8387
8388
        $element->addOption(get_lang('None'), 0, []);
8389
        $sessions = SessionManager::getListOfParentSessions();
8390
        $currentSessionId = $session?->getId();
8391
        foreach ($sessions as $id => $title) {
8392
            if ($id !== $currentSessionId) {
8393
                $attributes = [];
8394
                $element->addOption($title, $id, $attributes);
8395
            }
8396
        }
8397
        $element->setSelected($session?->getParentId() ?? 0);
8398
        $form->addElement($element);
8399
8400
        $form->addElement('html', '</div>');
8401
8402
        $js = $extra['jquery_ready_content'];
8403
8404
        return ['js' => $js];
8405
    }
8406
8407
    /**
8408
     * Saves the session picture.
8409
     *
8410
     * @param int    $sessionId
8411
     * @param array  $file
8412
     * @param string $crop
8413
     *
8414
     * @return false
8415
     */
8416
    public static function updateSessionPicture(
8417
        $sessionId,
8418
        $file,
8419
        string $crop = ''
8420
    ) {
8421
        if (empty($file)) {
8422
            return false;
8423
        }
8424
8425
        $sessionRepo = Container::getSessionRepository();
8426
        $assetRepo = Container::getAssetRepository();
8427
8428
        $asset = (new Asset())
8429
            ->setCategory(Asset::SESSION)
8430
            ->setTitle($file['name'])
8431
        ;
8432
        if (!empty($crop)) {
8433
            $asset->setCrop($crop);
8434
        }
8435
        $asset = $assetRepo->createFromRequest($asset, $file);
8436
8437
        /** @var Session $session */
8438
        $session = $sessionRepo->find($sessionId);
8439
        $session->setImage($asset);
8440
        $sessionRepo->update($session);
8441
    }
8442
8443
    /**
8444
     * Deletes de session picture as asset.
8445
     *
8446
     * @param int $sessionId
8447
     */
8448
    public static function deleteAsset(int $sessionId): void
8449
    {
8450
        $sessionRepo = Container::getSessionRepository();
8451
8452
        /** @var Session $session */
8453
        $session = $sessionRepo->find($sessionId);
8454
        $em = Database::getManager();
8455
        if ($session->hasImage()) {
8456
            $asset = $session->getImage();
8457
            $em->remove($asset);
8458
            $em->flush();
8459
        }
8460
    }
8461
8462
    /**
8463
     * Get the session picture url.
8464
     *
8465
     * @param Session $session
8466
     * @return string
8467
     */
8468
    public static function getSessionPictureUrl(Session $session): string
8469
    {
8470
        $assetRepo = Container::getAssetRepository();
8471
        $imageUrl = $assetRepo->getAssetUrl($session->getImage());
8472
8473
        return $imageUrl;
8474
    }
8475
8476
    /**
8477
     * Gets the number of rows in the session table filtered through the given
8478
     * array of parameters.
8479
     *
8480
     * @param array Array of options/filters/keys
8481
     *
8482
     * @return int The number of rows, or false on wrong param
8483
     * @assert ('a') === false
8484
     */
8485
    public static function get_count_admin_complete($options = [])
8486
    {
8487
        if (!is_array($options)) {
8488
            return false;
8489
        }
8490
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8491
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8492
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8493
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8494
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
8495
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8496
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8497
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
8498
8499
        $where = 'WHERE 1 = 1 AND u.active <> -1 ';
8500
8501
        if (api_is_session_admin() &&
8502
            'false' == api_get_setting('allow_session_admins_to_see_all_sessions')
8503
        ) {
8504
            $user_id = api_get_user_id();
8505
            $where .= ' AND (sru.relation_type = '.Session::SESSION_ADMIN." AND sru.user_id = $user_id) ";
8506
        } else {
8507
            $where .= ' AND sru.relation_type = '.Session::GENERAL_COACH.' ';
8508
        }
8509
8510
        $extraFieldTables = '';
8511
        if (!empty($options['where'])) {
8512
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8513
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8514
8515
            $options['where'] = str_replace(
8516
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8517
                [') GROUP BY s.title HAVING session_active = 1 ', " GROUP BY s.title HAVING session_active = 1 "],
8518
                $options['where']
8519
            );
8520
8521
            $options['where'] = str_replace(
8522
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8523
                [') GROUP BY s.title HAVING session_active = 0 ', " GROUP BY s.title HAVING session_active = '0' "],
8524
                $options['where']
8525
            );
8526
8527
            if (!empty($options['extra'])) {
8528
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8529
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8530
8531
                foreach ($options['extra'] as $extra) {
8532
                    $options['where'] = str_replace(
8533
                        $extra['field'],
8534
                        'fv.field_id = '.$extra['id'].' AND fvo.option_value',
8535
                        $options['where']
8536
                    );
8537
                    $extraFieldTables = "$tbl_session_field_values fv, $tbl_session_field_options fvo, ";
8538
                }
8539
            }
8540
            $where .= ' AND '.$options['where'];
8541
        }
8542
8543
        $today = api_get_utc_datetime();
8544
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.title,
8545
                        IF (
8546
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8547
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8548
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8549
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8550
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8551
                        , 1, 0) as session_active
8552
                       FROM $extraFieldTables $tbl_session s
8553
                       LEFT JOIN  $tbl_session_category sc
8554
                       ON s.session_category_id = sc.id
8555
                       INNER JOIN $tblSessionRelUser sru
8556
                       ON s.id = sru.session_id
8557
                       INNER JOIN $tbl_user u
8558
                       ON sru.user_id = u.id
8559
                       INNER JOIN $sessionCourseUserTable scu
8560
                       ON s.id = scu.session_id
8561
                       INNER JOIN $courseTable c
8562
                       ON c.id = scu.c_id
8563
                       $where ";
8564
8565
        if (api_is_multiple_url_enabled()) {
8566
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8567
            $access_url_id = api_get_current_access_url_id();
8568
            if (-1 != $access_url_id) {
8569
                $where .= " AND ar.access_url_id = $access_url_id ";
8570
                $query_rows = "SELECT count(*) as total_rows
8571
                               FROM $tbl_session s
8572
                               LEFT JOIN  $tbl_session_category sc
8573
                               ON s.session_category_id = sc.id
8574
                               INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
8575
                               INNER JOIN $tbl_user u
8576
                               ON sru.user_id = u.id
8577
                               INNER JOIN $table_access_url_rel_session ar
8578
                               ON ar.session_id = s.id $where ";
8579
            }
8580
        }
8581
8582
        $result = Database::query($query_rows);
8583
        $num = 0;
8584
        if (Database::num_rows($result)) {
8585
            $rows = Database::fetch_array($result);
8586
            $num = $rows['total_rows'];
8587
        }
8588
8589
        return $num;
8590
    }
8591
8592
    /**
8593
     * @param string $listType
8594
     * @param array  $extraFields
8595
     *
8596
     * @return array
8597
     */
8598
    public static function getGridColumns(
8599
        $listType = 'all',
8600
        $extraFields = [],
8601
        $addExtraFields = true
8602
    ) {
8603
        $showCount = ('true' === api_get_setting('session.session_list_show_count_users'));
8604
        // Column config
8605
        $operators = ['cn', 'nc'];
8606
        $date_operators = ['gt', 'ge', 'lt', 'le'];
8607
8608
        switch ($listType) {
8609
            case 'my_space':
8610
                $columns = [
8611
                    get_lang('Title'),
8612
                    get_lang('Date'),
8613
                    get_lang('Number of courses per session'),
8614
                    get_lang('Number of learners by session'),
8615
                    get_lang('Details'),
8616
                ];
8617
8618
                $columnModel = [
8619
                    ['name' => 'title', 'index' => 'title', 'align' => 'left'],
8620
                    ['name' => 'date', 'index' => 'access_start_date', 'align' => 'left'],
8621
                    [
8622
                        'name' => 'course_per_session',
8623
                        'index' => 'course_per_session',
8624
                        'sortable' => 'false',
8625
                        'search' => 'false',
8626
                    ],
8627
                    [
8628
                        'name' => 'student_per_session',
8629
                        'index' => 'student_per_session',
8630
                        'sortable' => 'false',
8631
                        'search' => 'false',
8632
                    ],
8633
                    [
8634
                        'name' => 'actions',
8635
                        'index' => 'actions',
8636
                        'sortable' => 'false',
8637
                        'search' => 'false',
8638
                    ],
8639
                ];
8640
                break;
8641
            case 'all':
8642
            case 'active':
8643
            case 'close':
8644
                $columns = [
8645
                    '#',
8646
                    get_lang('Title'),
8647
                    get_lang('Category'),
8648
                    get_lang('Start date to display'),
8649
                    get_lang('End date to display'),
8650
                    get_lang('Visibility'),
8651
                ];
8652
8653
                $columnModel = [
8654
                    [
8655
                        'name' => 'id',
8656
                        'index' => 's.id',
8657
                        'hidden' => 'true',
8658
                    ],
8659
                    [
8660
                        'name' => 'title',
8661
                        'index' => 's.title',
8662
                        'width' => '300',
8663
                        'align' => 'left',
8664
                        'search' => 'true',
8665
                        'searchoptions' => ['sopt' => $operators],
8666
                    ],
8667
                    [
8668
                        'name' => 'category_name',
8669
                        'index' => 'category_name',
8670
                        'align' => 'left',
8671
                        'search' => 'true',
8672
                        'searchoptions' => ['sopt' => $operators],
8673
                    ],
8674
                    [
8675
                        'name' => 'display_start_date',
8676
                        'index' => 'display_start_date',
8677
                        'align' => 'left',
8678
                        'width' => '200',
8679
                        'search' => 'true',
8680
                        'searchoptions' => [
8681
                            'dataInit' => 'date_pick_today',
8682
                            'sopt' => $date_operators,
8683
                        ],
8684
                    ],
8685
                    [
8686
                        'name' => 'display_end_date',
8687
                        'index' => 'display_end_date',
8688
                        'align' => 'left',
8689
                        'width' => '200',
8690
                        'search' => 'true',
8691
                        'searchoptions' => [
8692
                            'dataInit' => 'date_pick_one_month',
8693
                            'sopt' => $date_operators,
8694
                        ],
8695
                    ],
8696
                    [
8697
                        'name' => 'visibility',
8698
                        'index' => 'visibility',
8699
                        'align' => 'left',
8700
                        'search' => 'false',
8701
                    ],
8702
                ];
8703
8704
                if ($showCount) {
8705
                    $columns[] = get_lang('Users');
8706
                    $columnModel[] = [
8707
                        'name' => 'users',
8708
                        'index' => 'users',
8709
                        'align' => 'left',
8710
                        'width' => '100',
8711
                        'search' => 'false',
8712
                    ];
8713
8714
                    // ofaj
8715
                    $columns[] = get_lang('Teachers');
8716
                    $columnModel[] = [
8717
                        'name' => 'teachers',
8718
                        'index' => 'teachers',
8719
                        'align' => 'left',
8720
                        'search' => 'false',
8721
                    ];
8722
                }
8723
8724
                $columns[] = get_lang('Session status');
8725
                $list = self::getStatusList();
8726
                $listToString = '';
8727
                foreach ($list as $statusId => $status) {
8728
                    $listToString .= $statusId.':'.$status.';';
8729
                }
8730
8731
                $columnModel[] = [
8732
                    'name' => 'status',
8733
                    'index' => 'status',
8734
                    'align' => 'left',
8735
                    'width' => '120',
8736
                    'search' => 'true',
8737
                    'stype' => 'select',
8738
                    // for the bottom bar
8739
                    'searchoptions' => [
8740
                        'defaultValue' => '1',
8741
                        'value' => $listToString,
8742
                    ],
8743
                ];
8744
8745
                break;
8746
8747
            case 'simple':
8748
                $columns = [
8749
                    '#',
8750
                    get_lang('Title'),
8751
                    get_lang('Category'),
8752
                    get_lang('Session Display Start Date'),
8753
                    get_lang('Session Display End Date'),
8754
                    get_lang('Visibility'),
8755
                ];
8756
8757
                $columnModel = [
8758
                    [
8759
                        'name' => 'id',
8760
                        'index' => 's.id',
8761
                        'hidden' => 'true',
8762
                    ],
8763
                    [
8764
                        'name' => 'title',
8765
                        'index' => 's.title',
8766
                        'width' => '300',
8767
                        'align' => 'left',
8768
                        'search' => 'true',
8769
                        'searchoptions' => ['sopt' => $operators],
8770
                    ],
8771
                    [
8772
                        'name' => 'category_name',
8773
                        'index' => 'category_name',
8774
                        'align' => 'left',
8775
                        'search' => 'true',
8776
                        'searchoptions' => ['sopt' => $operators],
8777
                    ],
8778
                    [
8779
                        'name' => 'display_start_date',
8780
                        'index' => 'display_start_date',
8781
                        'align' => 'left',
8782
                        'width' => '200',
8783
                        'search' => 'true',
8784
                        'searchoptions' => [
8785
                            'dataInit' => 'date_pick_today',
8786
                            'sopt' => $date_operators,
8787
                        ],
8788
                    ],
8789
                    [
8790
                        'name' => 'display_end_date',
8791
                        'index' => 'display_end_date',
8792
                        'align' => 'left',
8793
                        'width' => '200',
8794
                        'search' => 'true',
8795
                        'searchoptions' => [
8796
                            'dataInit' => 'date_pick_one_month',
8797
                            'sopt' => $date_operators,
8798
                        ],
8799
                    ],
8800
                    [
8801
                        'name' => 'visibility',
8802
                        'index' => 'visibility',
8803
                        'align' => 'left',
8804
                        'search' => 'false',
8805
                    ],
8806
                ];
8807
8808
                if ($showCount) {
8809
                    $columns[] = get_lang('Users');
8810
                    $columnModel[] = [
8811
                        'name' => 'users',
8812
                        'index' => 'users',
8813
                        'align' => 'left',
8814
                        'width' => '100',
8815
                        'search' => 'false',
8816
                    ];
8817
8818
                    // ofaj
8819
                    $columns[] = get_lang('Teachers');
8820
                    $columnModel[] = [
8821
                        'name' => 'teachers',
8822
                        'index' => 'teachers',
8823
                        'align' => 'left',
8824
                        'search' => 'false',
8825
                    ];
8826
                }
8827
8828
                $columns[] = get_lang('Session status');
8829
                $list = self::getStatusList();
8830
                $listToString = '';
8831
                foreach ($list as $statusId => $status) {
8832
                    $listToString .= $statusId.':'.$status.';';
8833
                }
8834
8835
                $columnModel[] = ['name' => 'status', 'index' => 'status', 'align' => 'left', 'search' => 'true', 'stype' => 'select',
8836
                    // for the bottom bar
8837
                    'searchoptions' => [
8838
                        'defaultValue' => '1',
8839
                        'value' => $listToString,
8840
                    ],
8841
                ];
8842
8843
                break;
8844
            case 'complete':
8845
                $columns = [
8846
                    get_lang('Title'),
8847
                    get_lang('Start date to display'),
8848
                    get_lang('End date to display'),
8849
                    get_lang('Coach'),
8850
                    get_lang('Status'),
8851
                    get_lang('Visibility'),
8852
                    get_lang('Course title'),
8853
                ];
8854
                $columnModel = [
8855
                    [
8856
                        'name' => 'title',
8857
                        'index' => 's.title',
8858
                        'width' => '300',
8859
                        'align' => 'left',
8860
                        'search' => 'true',
8861
                        'searchoptions' => ['sopt' => $operators],
8862
                    ],
8863
                    [
8864
                        'name' => 'display_start_date',
8865
                        'index' => 'display_start_date',
8866
                        'align' => 'left',
8867
                        'width' => '200',
8868
                        'search' => 'true',
8869
                        'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators],
8870
                    ],
8871
                    [
8872
                        'name' => 'display_end_date',
8873
                        'index' => 'display_end_date',
8874
                        'width' => '200',
8875
                        'align' => 'left',
8876
                        'search' => 'true',
8877
                        'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators],
8878
                    ],
8879
                    [
8880
                        'name' => 'coach_name',
8881
                        'index' => 'coach_name',
8882
                        'align' => 'left',
8883
                        'search' => 'false',
8884
                        'searchoptions' => ['sopt' => $operators],
8885
                    ],
8886
                    [
8887
                        'name' => 'session_active',
8888
                        'index' => 'session_active',
8889
                        'align' => 'left',
8890
                        'search' => 'true',
8891
                        'stype' => 'select',
8892
                        // for the bottom bar
8893
                        'searchoptions' => [
8894
                            'defaultValue' => '1',
8895
                            'value' => '1:'.get_lang('Active').';0:'.get_lang('Inactive'),
8896
                        ],
8897
                        // for the top bar
8898
                        'editoptions' => [
8899
                            'value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang(
8900
                                    'Inactive'
8901
                                ),
8902
                        ],
8903
                    ],
8904
                    [
8905
                        'name' => 'visibility',
8906
                        'index' => 'visibility',
8907
                        'align' => 'left',
8908
                        'search' => 'false',
8909
                    ],
8910
                    [
8911
                        'name' => 'course_title',
8912
                        'index' => 'course_title',
8913
                        'hidden' => 'true',
8914
                        'search' => 'true',
8915
                        'searchoptions' => ['searchhidden' => 'true', 'sopt' => $operators],
8916
                    ],
8917
                ];
8918
8919
                break;
8920
            case 'replication':
8921
            case 'custom':
8922
                $columns = [
8923
                    '#',
8924
                    get_lang('Title'),
8925
                    get_lang('Category'),
8926
                    get_lang('Start date to display'),
8927
                    get_lang('End date to display'),
8928
                    get_lang('Visibility'),
8929
                ];
8930
                $columnModel = [
8931
                    [
8932
                        'name' => 'id',
8933
                        'index' => 's.id',
8934
                        'hidden' => 'true',
8935
                    ],
8936
                    [
8937
                        'name' => 'title',
8938
                        'index' => 's.title',
8939
                        'width' => '260px',
8940
                        'width' => '300',
8941
                        'align' => 'left',
8942
                        'search' => 'true',
8943
                        'searchoptions' => ['sopt' => $operators],
8944
                    ],
8945
                    [
8946
                        'name' => 'category_name',
8947
                        'index' => 'category_name',
8948
                        'align' => 'left',
8949
                        'search' => 'true',
8950
                        'searchoptions' => ['sopt' => $operators],
8951
                    ],
8952
                    [
8953
                        'name' => 'display_start_date',
8954
                        'index' => 'display_start_date',
8955
                        'align' => 'left',
8956
                        'width' => '200',
8957
                        'search' => 'true',
8958
                        'searchoptions' => [
8959
                            'dataInit' => 'date_pick_today',
8960
                            'sopt' => $date_operators,
8961
                        ],
8962
                    ],
8963
                    [
8964
                        'name' => 'display_end_date',
8965
                        'index' => 'display_end_date',
8966
                        'align' => 'left',
8967
                        'width' => '200',
8968
                        'search' => 'true',
8969
                        'searchoptions' => [
8970
                            'dataInit' => 'date_pick_one_month',
8971
                            'sopt' => $date_operators,
8972
                        ],
8973
                    ],
8974
                    [
8975
                        'name' => 'visibility',
8976
                        'index' => 'visibility',
8977
                        'align' => 'left',
8978
                        'search' => 'false',
8979
                    ],
8980
                ];
8981
8982
                if ($showCount) {
8983
                    $columns[] = get_lang('Users');
8984
                    $columnModel[] = [
8985
                        'name' => 'users',
8986
                        'index' => 'users',
8987
                        'align' => 'left',
8988
                        'width' => '100',
8989
                        'search' => 'false',
8990
                    ];
8991
8992
                    // ofaj
8993
                    $columns[] = get_lang('Teachers');
8994
                    $columnModel[] = [
8995
                        'name' => 'teachers',
8996
                        'index' => 'teachers',
8997
                        'align' => 'left',
8998
                        'search' => 'false',
8999
                    ];
9000
                }
9001
9002
                $columns[] = get_lang('Session status');
9003
                $list = self::getStatusList();
9004
                $listToString = '';
9005
                foreach ($list as $statusId => $status) {
9006
                    $listToString .= $statusId.':'.$status.';';
9007
                }
9008
9009
                $columnModel[] = [
9010
                    'name' => 'status',
9011
                    'index' => 'status',
9012
                    'align' => 'left',
9013
                    'width' => '120',
9014
                    'search' => 'true',
9015
                    'stype' => 'select',
9016
                    // for the bottom bar
9017
                    'searchoptions' => [
9018
                        'defaultValue' => '1',
9019
                        'value' => $listToString,
9020
                    ],
9021
                ];
9022
9023
                break;
9024
        }
9025
9026
        if (!empty($extraFields)) {
9027
            foreach ($extraFields as $field) {
9028
                $columns[] = $field['display_text'];
9029
                $columnModel[] = [
9030
                    'name' => $field['variable'],
9031
                    'index' => $field['variable'],
9032
                    'align' => 'center',
9033
                    'search' => 'false',
9034
                ];
9035
            }
9036
        }
9037
9038
        // Inject extra session fields
9039
        $rules = [];
9040
        if ($addExtraFields) {
9041
            $sessionField = new ExtraFieldModel('session');
9042
            $rules = $sessionField->getRules($columns, $columnModel);
9043
        }
9044
9045
        if (!in_array('actions', array_column($columnModel, 'name'))) {
9046
            $columnModel[] = [
9047
                'name' => 'actions',
9048
                'index' => 'actions',
9049
                'align' => 'left',
9050
                'formatter' => 'action_formatter',
9051
                'sortable' => 'false',
9052
                'search' => 'false',
9053
            ];
9054
            $columns[] = get_lang('Actions');
9055
        }
9056
9057
        $columnName = [];
9058
        foreach ($columnModel as $col) {
9059
            $columnName[] = $col['name'];
9060
        }
9061
9062
        $return = [
9063
            'columns' => $columns,
9064
            'column_model' => $columnModel,
9065
            'rules' => $rules,
9066
            'simple_column_name' => $columnName,
9067
        ];
9068
9069
        return $return;
9070
    }
9071
9072
    /**
9073
     * Converts all dates sent through the param array (given form) to correct dates with timezones.
9074
     *
9075
     * @param array The dates The same array, with times converted
9076
     * @param bool $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
9077
     *
9078
     * @return array The same array, with times converted
9079
     */
9080
    public static function convert_dates_to_local($params, $applyFormat = false)
9081
    {
9082
        if (!is_array($params)) {
9083
            return false;
9084
        }
9085
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
9086
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
9087
9088
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
9089
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
9090
9091
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
9092
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
9093
9094
        if ($applyFormat) {
9095
            if (isset($params['display_start_date'])) {
9096
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
9097
            }
9098
9099
            if (isset($params['display_end_date'])) {
9100
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
9101
            }
9102
9103
            if (isset($params['access_start_date'])) {
9104
                $params['access_start_date'] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
9105
            }
9106
9107
            if (isset($params['access_end_date'])) {
9108
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
9109
            }
9110
9111
            if (isset($params['coach_access_start_date'])) {
9112
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
9113
            }
9114
9115
            if (isset($params['coach_access_end_date'])) {
9116
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
9117
            }
9118
        }
9119
9120
        return $params;
9121
    }
9122
9123
    /**
9124
     * Gets the admin session list callback of the session/session_list.php
9125
     * page with all user/details in the right fomat.
9126
     *
9127
     * @param array $options
9128
     *
9129
     * @return array Array of rows results
9130
     * @asset ('a') === false
9131
     */
9132
    public static function get_sessions_admin_complete($options = [])
9133
    {
9134
        if (!is_array($options)) {
9135
            return false;
9136
        }
9137
9138
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
9139
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
9140
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
9141
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9142
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
9143
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9144
9145
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
9146
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
9147
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
9148
9149
        $where = 'WHERE 1 = 1 ';
9150
9151
        if (!api_is_platform_admin()) {
9152
            if (api_is_session_admin() &&
9153
                'false' == api_get_setting('allow_session_admins_to_manage_all_sessions')
9154
            ) {
9155
                $user_id = api_get_user_id();
9156
                $where .= ' AND (sru.relation_type = '.Session::SESSION_ADMIN." AND sru.user_id = $user_id) ";
9157
            } else {
9158
                $where .= ' AND sru.relation_type = '.Session::GENERAL_COACH.' ';
9159
            }
9160
        }
9161
9162
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
9163
        if (api_is_western_name_order()) {
9164
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
9165
        }
9166
9167
        $today = api_get_utc_datetime();
9168
        $injectExtraFields = null;
9169
        $extra_fields_info = [];
9170
9171
        //for now only sessions
9172
        $extra_field = new ExtraFieldModel('session');
9173
        $double_fields = [];
9174
        $extra_field_option = new ExtraFieldOption('session');
9175
9176
        if (isset($options['extra'])) {
9177
            $extra_fields = $options['extra'];
9178
            if (!empty($extra_fields)) {
9179
                foreach ($extra_fields as $extra) {
9180
                    $injectExtraFields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
9181
                    if (isset($extra_fields_info[$extra['id']])) {
9182
                        $info = $extra_fields_info[$extra['id']];
9183
                    } else {
9184
                        $info = $extra_field->get($extra['id']);
9185
                        $extra_fields_info[$extra['id']] = $info;
9186
                    }
9187
9188
                    if (ExtraFieldModel::FIELD_TYPE_DOUBLE_SELECT == $info['value_type']) {
9189
                        $double_fields[$info['id']] = $info;
9190
                    }
9191
                }
9192
            }
9193
        }
9194
9195
        $options_by_double = [];
9196
        foreach ($double_fields as $double) {
9197
            $my_options = $extra_field_option->get_field_options_by_field(
9198
                $double['id'],
9199
                true
9200
            );
9201
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
9202
        }
9203
9204
        //sc.title as category_name,
9205
        $select = "
9206
                SELECT * FROM (
9207
                    SELECT DISTINCT
9208
                        IF (
9209
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
9210
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
9211
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
9212
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
9213
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
9214
                        , 1, 0) as session_active,
9215
                s.title,
9216
                s.nbr_courses,
9217
                s.nbr_users,
9218
                s.display_start_date,
9219
                s.display_end_date,
9220
                $coach_name,
9221
                access_start_date,
9222
                access_end_date,
9223
                s.visibility,
9224
                u.id as user_id,
9225
                $injectExtraFields
9226
                c.title as course_title,
9227
                s.id ";
9228
9229
        if (!empty($options['where'])) {
9230
            if (!empty($options['extra'])) {
9231
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
9232
                $options['where'] = str_replace('AND', 'OR', $options['where']);
9233
                foreach ($options['extra'] as $extra) {
9234
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
9235
                }
9236
            }
9237
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
9238
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
9239
            $options['where'] = str_replace(
9240
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
9241
                [') GROUP BY s.title HAVING session_active = 1 ', " GROUP BY s.title HAVING session_active = 1 "],
9242
                $options['where']
9243
            );
9244
9245
            $options['where'] = str_replace(
9246
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
9247
                [') GROUP BY s.title HAVING session_active = 0 ', " GROUP BY s.title HAVING session_active = '0' "],
9248
                $options['where']
9249
            );
9250
9251
            $where .= ' AND '.$options['where'];
9252
        }
9253
9254
        $limit = '';
9255
        if (!empty($options['limit'])) {
9256
            $limit = ' LIMIT '.$options['limit'];
9257
        }
9258
9259
        $query = "$select FROM $tbl_session s
9260
                    LEFT JOIN $tbl_session_field_values fv
9261
                    ON (fv.item_id = s.id)
9262
                    LEFT JOIN $extraFieldTable f
9263
                    ON f.id = fv.field_id
9264
                    LEFT JOIN $tbl_session_field_options fvo
9265
                    ON (fv.field_id = fvo.field_id)
9266
                    LEFT JOIN $tbl_session_rel_course src
9267
                    ON (src.session_id = s.id)
9268
                    LEFT JOIN $tbl_course c
9269
                    ON (src.c_id = c.id)
9270
                    LEFT JOIN $tbl_session_category sc
9271
                    ON (s.session_category_id = sc.id)
9272
                    INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
9273
                    INNER JOIN $tbl_user u
9274
                    ON sru.user_id = u.id
9275
                    $where
9276
                    $limit
9277
        ";
9278
9279
        if (api_is_multiple_url_enabled()) {
9280
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9281
            $access_url_id = api_get_current_access_url_id();
9282
            if (-1 != $access_url_id) {
9283
                $query = "$select
9284
                    FROM $tbl_session s
9285
                    LEFT JOIN $tbl_session_field_values fv
9286
                    ON (fv.item_id = s.id)
9287
                    LEFT JOIN $tbl_session_field_options fvo
9288
                    ON (fv.field_id = fvo.field_id)
9289
                    LEFT JOIN $tbl_session_rel_course src
9290
                    ON (src.session_id = s.id)
9291
                    LEFT JOIN $tbl_course c
9292
                    ON (src.c_id = c.id)
9293
                    LEFT JOIN $tbl_session_category sc
9294
                    ON (s.session_category_id = sc.id)
9295
                    INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
9296
                    INNER JOIN $tbl_user u
9297
                    ON sru.user_id = u.id
9298
                    INNER JOIN $table_access_url_rel_session ar
9299
                    ON (ar.session_id = s.id AND ar.access_url_id = $access_url_id)
9300
                    $where
9301
                    $limit
9302
                ";
9303
            }
9304
        }
9305
9306
        $query .= ') AS s';
9307
9308
        if (!empty($options['order'])) {
9309
            $query .= ' ORDER BY '.$options['order'];
9310
        }
9311
9312
        $result = Database::query($query);
9313
9314
        $acceptIcon = Display::getMdiIcon(StateIcon::ACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Active'));
9315
9316
        $errorIcon = Display::getMdiIcon(StateIcon::INACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Inactive'));
9317
9318
        $formatted_sessions = [];
9319
        if (Database::num_rows($result)) {
9320
            $sessions = Database::store_result($result, 'ASSOC');
9321
            foreach ($sessions as $session) {
9322
                $session_id = $session['id'];
9323
                $session['title'] = Display::url($session['title'], "resume_session.php?id_session=".$session['id']);
9324
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
9325
                if (1 == $session['session_active']) {
9326
                    $session['session_active'] = $acceptIcon;
9327
                } else {
9328
                    $session['session_active'] = $errorIcon;
9329
                }
9330
9331
                $session = self::convert_dates_to_local($session);
9332
9333
                switch ($session['visibility']) {
9334
                    case SESSION_VISIBLE_READ_ONLY: //1
9335
                        $session['visibility'] = get_lang('Read only');
9336
                        break;
9337
                    case SESSION_VISIBLE:           //2
9338
                    case SESSION_AVAILABLE:         //4
9339
                        $session['visibility'] = get_lang('Visible');
9340
                        break;
9341
                    case SESSION_INVISIBLE:         //3
9342
                        $session['visibility'] = api_ucfirst(get_lang('invisible'));
9343
                        break;
9344
                }
9345
9346
                // Cleaning double selects
9347
                foreach ($session as $key => &$value) {
9348
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
9349
                        $options = explode('::', $value);
9350
                    }
9351
                    $original_key = $key;
9352
9353
                    if (false === strpos($key, '_second')) {
9354
                    } else {
9355
                        $key = str_replace('_second', '', $key);
9356
                    }
9357
9358
                    if (isset($options_by_double[$key])) {
9359
                        if (isset($options[0])) {
9360
                            if (isset($options_by_double[$key][$options[0]])) {
9361
                                if (false === strpos($original_key, '_second')) {
9362
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
9363
                                } else {
9364
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
9365
                                }
9366
                            }
9367
                        }
9368
                    }
9369
                }
9370
9371
                // Magic filter
9372
                if (isset($formatted_sessions[$session_id])) {
9373
                    $formatted_sessions[$session_id] = self::compareArraysToMerge(
9374
                        $formatted_sessions[$session_id],
9375
                        $session
9376
                    );
9377
                } else {
9378
                    $formatted_sessions[$session_id] = $session;
9379
                }
9380
            }
9381
        }
9382
9383
        return $formatted_sessions;
9384
    }
9385
9386
    /**
9387
     * Compare two arrays.
9388
     *
9389
     * @param array $array1
9390
     * @param array $array2
9391
     *
9392
     * @return array
9393
     */
9394
    public static function compareArraysToMerge($array1, $array2)
9395
    {
9396
        if (empty($array2)) {
9397
            return $array1;
9398
        }
9399
        foreach ($array1 as $key => $item) {
9400
            if (!isset($array1[$key])) {
9401
                //My string is empty try the other one
9402
                if (isset($array2[$key]) && !empty($array2[$key])) {
9403
                    $array1[$key] = $array2[$key];
9404
                }
9405
            }
9406
        }
9407
9408
        return $array1;
9409
    }
9410
9411
    /**
9412
     * Get link to the admin page for this session.
9413
     *
9414
     * @param int $id Session ID
9415
     *
9416
     * @return mixed URL to the admin page to manage the session, or false on error
9417
     */
9418
    public static function getAdminPath($id)
9419
    {
9420
        $id = (int) $id;
9421
        $session = self::fetch($id);
9422
        if (empty($session)) {
9423
            return false;
9424
        }
9425
9426
        return api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$id;
9427
    }
9428
9429
    /**
9430
     * Get link to the user page for this session.
9431
     * If a course is provided, build the link to the course.
9432
     *
9433
     * @param int $id       Session ID
9434
     * @param int $courseId Course ID (optional) in case the link has to send straight to the course
9435
     *
9436
     * @return mixed URL to the page to use the session, or false on error
9437
     */
9438
    public static function getPath($id, $courseId = 0)
9439
    {
9440
        $id = (int) $id;
9441
        $session = self::fetch($id);
9442
        if (empty($session)) {
9443
            return false;
9444
        }
9445
        if (empty($courseId)) {
9446
            return api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$id;
9447
        } else {
9448
            $courseInfo = api_get_course_info_by_id($courseId);
9449
            if ($courseInfo) {
9450
                return $courseInfo['course_public_url'].'?id_session='.$id;
9451
            }
9452
        }
9453
9454
        return false;
9455
    }
9456
9457
    /**
9458
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9459
     * where course id_course is in sessions id_session1, id_session2
9460
     * for course where user is coach
9461
     * i.e. coach for the course or
9462
     * main coach for a session the course is in
9463
     * for a session category (or woth no session category if empty).
9464
     *
9465
     * @param int $userId
9466
     *
9467
     * @return array
9468
     */
9469
    public static function getSessionCourseForUser($userId)
9470
    {
9471
        // list of COURSES where user is COURSE session coach
9472
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
9473
        // list of courses where user is MAIN session coach
9474
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
9475
        // merge these 2 array
9476
        $listResCourseSession = $listCourseCourseCoachSession;
9477
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
9478
            if (isset($listResCourseSession[$courseId2])) {
9479
                // if sessionId array exists for this course
9480
                // same courseId, merge the list of session
9481
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
9482
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
9483
                        $listResCourseSession[$courseId2][] = $sessionId2;
9484
                    }
9485
                }
9486
            } else {
9487
                $listResCourseSession[$courseId2] = $listSessionId2;
9488
            }
9489
        }
9490
9491
        return $listResCourseSession;
9492
    }
9493
9494
    /**
9495
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9496
     * where course id_course is in sessions id_session1, id_session2.
9497
     *
9498
     * @param int $userId
9499
     *
9500
     * @return array
9501
     */
9502
    public static function getCoursesForCourseSessionCoach($userId)
9503
    {
9504
        $userId = (int) $userId;
9505
        $listResCourseSession = [];
9506
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9507
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9508
9509
        $sql = "SELECT session_id, c_id, c.id
9510
                FROM $tblSessionRelCourseRelUser srcru
9511
                LEFT JOIN $tblCourse c
9512
                ON c.id = srcru.c_id
9513
                WHERE
9514
                    srcru.user_id = $userId AND
9515
                    srcru.status = ".Session::COURSE_COACH;
9516
9517
        $res = Database::query($sql);
9518
9519
        while ($data = Database::fetch_assoc($res)) {
9520
            if (api_get_session_visibility($data['session_id'])) {
9521
                if (!isset($listResCourseSession[$data['id']])) {
9522
                    $listResCourseSession[$data['id']] = [];
9523
                }
9524
                $listResCourseSession[$data['id']][] = $data['session_id'];
9525
            }
9526
        }
9527
9528
        return $listResCourseSession;
9529
    }
9530
9531
    /**
9532
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9533
     * where course id_course is in sessions id_session1, id_session2.
9534
     *
9535
     * @param $userId
9536
     *
9537
     * @return array
9538
     */
9539
    public static function getCoursesForMainSessionCoach($userId)
9540
    {
9541
        $userId = (int) $userId;
9542
        $user = api_get_user_entity($userId);
9543
        $listResCourseSession = [];
9544
9545
        $sessions = $user->getSessionsAsGeneralCoach();
9546
9547
        foreach ($sessions as $session) {
9548
            $sessionId = $session->getId();
9549
            $listCoursesInSession = self::getCoursesInSession($sessionId);
9550
            foreach ($listCoursesInSession as $i => $courseId) {
9551
                if (api_get_session_visibility($sessionId)) {
9552
                    if (!isset($listResCourseSession[$courseId])) {
9553
                        $listResCourseSession[$courseId] = [];
9554
                    }
9555
                    $listResCourseSession[$courseId][] = $sessionId;
9556
                }
9557
            }
9558
        }
9559
9560
        return $listResCourseSession;
9561
    }
9562
9563
    /**
9564
     * Return an array of course_id used in session $sessionId.
9565
     *
9566
     * @param $sessionId
9567
     *
9568
     * @return array
9569
     */
9570
    public static function getCoursesInSession($sessionId)
9571
    {
9572
        if (empty($sessionId)) {
9573
            return [];
9574
        }
9575
9576
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9577
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9578
9579
        // list of course in this session
9580
        $sql = "SELECT session_id, c.id
9581
                FROM $tblSessionRelCourse src
9582
                LEFT JOIN $tblCourse c
9583
                ON c.id = src.c_id
9584
                WHERE session_id = ".intval($sessionId);
9585
        $res = Database::query($sql);
9586
9587
        $listResultsCourseId = [];
9588
        while ($data = Database::fetch_assoc($res)) {
9589
            $listResultsCourseId[] = $data['id'];
9590
        }
9591
9592
        return $listResultsCourseId;
9593
    }
9594
9595
    /**
9596
     * Return an array of courses in session for user
9597
     * and for each courses the list of session that use this course for user.
9598
     *
9599
     * [0] => array
9600
     *      userCatId
9601
     *      userCatTitle
9602
     *      courseInUserCatList
9603
     *          [0] => array
9604
     *              courseId
9605
     *              title
9606
     *              courseCode
9607
     *              sessionCatList
9608
     *                  [0] => array
9609
     *                      catSessionId
9610
     *                      catSessionName
9611
     *                      sessionList
9612
     *                          [0] => array
9613
     *                              sessionId
9614
     *                              sessionName
9615
     *
9616
     * @param int $userId
9617
     *
9618
     * @return array
9619
     */
9620
    public static function getNamedSessionCourseForCoach($userId)
9621
    {
9622
        $listResults = [];
9623
        $listCourseSession = self::getSessionCourseForUser($userId);
9624
        foreach ($listCourseSession as $courseId => $listSessionId) {
9625
            // Course info
9626
            $courseInfo = api_get_course_info_by_id($courseId);
9627
            $listOneCourse = [];
9628
            $listOneCourse['courseId'] = $courseId;
9629
            $listOneCourse['title'] = $courseInfo['title'];
9630
            //$listOneCourse['courseCode'] = $courseInfo['code'];
9631
            $listOneCourse['course'] = $courseInfo;
9632
            $listOneCourse['sessionCatList'] = [];
9633
            $listCat = [];
9634
            foreach ($listSessionId as $i => $sessionId) {
9635
                // here we got all session for this course
9636
                // lets check there session categories
9637
                $sessionInfo = self::fetch($sessionId);
9638
                $catId = $sessionInfo['session_category_id'];
9639
                if (!isset($listCat[$catId])) {
9640
                    $listCatInfo = self::get_session_category($catId);
9641
                    if ($listCatInfo) {
9642
                        $listCat[$catId] = [];
9643
                        $listCat[$catId]['catSessionId'] = $catId;
9644
                        $listCat[$catId]['catSessionName'] = $listCatInfo['title'];
9645
                        $listCat[$catId]['sessionList'] = [];
9646
                    }
9647
                }
9648
                $listSessionInfo = self::fetch($sessionId);
9649
                $listSessionIdName = [
9650
                    'sessionId' => $sessionId,
9651
                    'sessionName' => $listSessionInfo['title'],
9652
                ];
9653
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
9654
            }
9655
            // sort $listCat by catSessionName
9656
            usort($listCat, 'self::compareBySessionName');
9657
            // in each catSession sort sessionList by sessionName
9658
            foreach ($listCat as $i => $listCatSessionInfo) {
9659
                $listSessionList = $listCatSessionInfo['sessionList'];
9660
                usort($listSessionList, 'self::compareCatSessionInfo');
9661
                $listCat[$i]['sessionList'] = $listSessionList;
9662
            }
9663
9664
            $listOneCourse['sessionCatList'] = $listCat;
9665
            //$listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
9666
        }
9667
9668
        // sort by user course cat
9669
        uasort($listResults, 'self::compareByUserCourseCat');
9670
9671
        // sort by course title
9672
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
9673
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
9674
            uasort($courseInUserCatList, 'self::compareByCourse');
9675
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
9676
        }
9677
9678
        return $listResults;
9679
    }
9680
9681
    /**
9682
     * @param int $userId
9683
     * @param int $courseId
9684
     *
9685
     * @return array
9686
     */
9687
    public static function searchCourseInSessionsFromUser($userId, $courseId)
9688
    {
9689
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9690
        $userId = (int) $userId;
9691
        $courseId = (int) $courseId;
9692
        if (empty($userId) || empty($courseId)) {
9693
            return [];
9694
        }
9695
9696
        $sql = "SELECT * FROM $table
9697
                WHERE c_id = $courseId AND user_id = $userId";
9698
        $result = Database::query($sql);
9699
9700
        return Database::store_result($result, 'ASSOC');
9701
    }
9702
9703
    /**
9704
     * Subscribe and redirect to session after inscription.
9705
     */
9706
    public static function redirectToSession()
9707
    {
9708
        $sessionId = (int) ChamiloSession::read('session_redirect');
9709
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
9710
        if ($sessionId) {
9711
            $sessionInfo = api_get_session_info($sessionId);
9712
            if (!empty($sessionInfo)) {
9713
                $userId = api_get_user_id();
9714
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
9715
                if ($response) {
9716
                    $urlToRedirect = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
9717
                    if (!empty($onlyOneCourseSessionToRedirect)) {
9718
                        $urlToRedirect = api_get_path(WEB_PATH).
9719
                            'courses/'.$onlyOneCourseSessionToRedirect.'/index.php?id_session='.$sessionId;
9720
                    }
9721
9722
                    header('Location: '.$urlToRedirect);
9723
                    exit;
9724
                }
9725
            }
9726
        }
9727
    }
9728
9729
    /**
9730
     * @return int
9731
     */
9732
    public static function getCountUsersInCourseSession(Course $course, Session $session)
9733
    {
9734
        $url = api_get_url_entity(api_get_current_access_url_id());
9735
9736
        return Database::getManager()
9737
            ->createQuery("
9738
                SELECT COUNT(scu)
9739
                FROM ChamiloCoreBundle:SessionRelCourseRelUser scu
9740
                INNER JOIN ChamiloCoreBundle:SessionRelUser su
9741
                    WITH scu.user = su.user
9742
                    AND scu.session = su.session
9743
                INNER JOIN ChamiloCoreBundle:AccessUrlRelUser a
9744
                    WITH a.user = su.user
9745
                WHERE
9746
                    scu.course = :course AND
9747
                    su.relationType <> :relationType AND
9748
                    scu.session = :session AND
9749
                    a.url = :url
9750
            ")
9751
            ->setParameters([
9752
                'course' => $course->getId(),
9753
                'relationType' => Session::DRH,
9754
                'session' => $session->getId(),
9755
                'url' => $url,
9756
            ])
9757
            ->getSingleScalarResult();
9758
    }
9759
9760
    /**
9761
     * Get course IDs where user in not subscribed in session.
9762
     *
9763
     * @return array
9764
     */
9765
    public static function getAvoidedCoursesInSession(User $user, Session $session)
9766
    {
9767
        $courseIds = [];
9768
9769
        /** @var SessionRelCourse $sessionCourse */
9770
        foreach ($session->getCourses() as $sessionCourse) {
9771
            /** @var Course $course */
9772
            $course = $sessionCourse->getCourse();
9773
9774
            if ($session->getUserInCourse($user, $course)->count()) {
9775
                continue;
9776
            }
9777
9778
            $courseIds[] = $course->getId();
9779
        }
9780
9781
        return $courseIds;
9782
    }
9783
9784
    /**
9785
     * @param int             $userId
9786
     * @param int             $sessionId
9787
     * @param ExtraFieldValue $extraFieldValue
9788
     * @param string          $collapsableLink
9789
     *
9790
     * @return array
9791
     */
9792
    public static function getCollapsableData($userId, $sessionId, $extraFieldValue, $collapsableLink)
9793
    {
9794
        $collapsed = 0;
9795
9796
        // Get default collapsed value in extra field
9797
        $value = $extraFieldValue->get_values_by_handler_and_field_variable($sessionId, 'collapsed');
9798
        if (!empty($value) && isset($value['value'])) {
9799
            $collapsed = $value['value'];
9800
        }
9801
9802
        $userRelSession = self::getUserSession($userId, $sessionId);
9803
9804
        if ($userRelSession) {
9805
            if (isset($userRelSession['collapsed']) && '' != $userRelSession['collapsed']) {
9806
                $collapsed = $userRelSession['collapsed'];
9807
            }
9808
        } else {
9809
            return ['collapsed' => $collapsed, 'collapsable_link' => '&nbsp;'];
9810
        }
9811
9812
        $link = $collapsableLink.'&session_id='.$sessionId.'&value=1';
9813
        $image = '<i class="fa fa-folder-open"></i>';
9814
        if (1 == $collapsed) {
9815
            $link = $collapsableLink.'&session_id='.$sessionId.'&value=0';
9816
            $image = '<i class="fa fa-folder"></i>';
9817
        }
9818
9819
        $link = Display::url(
9820
            $image,
9821
            $link
9822
        );
9823
9824
        return ['collapsed' => $collapsed, 'collapsable_link' => $link];
9825
    }
9826
9827
    /**
9828
     * Converts "start date" and "end date" to "From start date to end date" string.
9829
     *
9830
     * @param string|DateTime $startDate
9831
     * @param string|DateTime $endDate
9832
     * @param bool   $showTime
9833
     * @param bool   $dateHuman
9834
     *
9835
     * @return string
9836
     */
9837
    public static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
9838
    {
9839
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
9840
        $startDateToLocal = api_get_local_time(
9841
            $startDate,
9842
            null,
9843
            null,
9844
            true,
9845
            $showTime,
9846
            $dateHuman
9847
        );
9848
        $endDateToLocal = api_get_local_time(
9849
            $endDate,
9850
            null,
9851
            null,
9852
            true,
9853
            $showTime,
9854
            $dateHuman
9855
        );
9856
9857
        $format = $showTime ? DATE_TIME_FORMAT_LONG_24H : DATE_FORMAT_LONG_NO_DAY;
9858
9859
        $result = '';
9860
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
9861
            $result = sprintf(
9862
                get_lang('From %s to %s'),
9863
                api_format_date($startDateToLocal, $format),
9864
                api_format_date($endDateToLocal, $format)
9865
            );
9866
        } else {
9867
            if (!empty($startDateToLocal)) {
9868
                $result = get_lang('From').' '.api_format_date($startDateToLocal, $format);
9869
            }
9870
            if (!empty($endDateToLocal)) {
9871
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, $format);
9872
            }
9873
        }
9874
        if (empty($result)) {
9875
            $result = get_lang('No time limits');
9876
        }
9877
9878
        return $result;
9879
    }
9880
9881
    /**
9882
     * @param int $id
9883
     */
9884
    public static function getSessionChangeUserReason($id): string
9885
    {
9886
        $reasons = self::getSessionChangeUserReasons();
9887
9888
        return $reasons[$id] ?? '';
9889
    }
9890
9891
    public static function getSessionChangeUserReasons(): array
9892
    {
9893
        return [
9894
            self::SESSION_CHANGE_USER_REASON_SCHEDULE => get_lang('ScheduleChanged'),
9895
            self::SESSION_CHANGE_USER_REASON_CLASSROOM => get_lang('ClassRoomChanged'),
9896
            self::SESSION_CHANGE_USER_REASON_LOCATION => get_lang('LocationChanged'),
9897
            //self::SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION => get_lang('EnrollmentAnnulation'),
9898
        ];
9899
    }
9900
9901
    public static function getStatusList()
9902
    {
9903
        return [
9904
            self::STATUS_PLANNED => get_lang('Planned'),
9905
            self::STATUS_PROGRESS => get_lang('InProgress'),
9906
            self::STATUS_FINISHED => get_lang('Finished'),
9907
            self::STATUS_CANCELLED => get_lang('Cancelled'),
9908
        ];
9909
    }
9910
9911
    public static function getStatusLabel($status)
9912
    {
9913
        $list = self::getStatusList();
9914
9915
        if (!isset($list[$status])) {
9916
            return get_lang('No status');
9917
        }
9918
9919
        return $list[$status];
9920
    }
9921
9922
    public static function getDefaultSessionTab()
9923
    {
9924
        $default = 'all';
9925
        $view = api_get_setting('session.default_session_list_view');
9926
9927
        if ('false' !== $view && !empty($view)) {
9928
            $default = $view;
9929
        }
9930
9931
        return $default;
9932
    }
9933
9934
    /**
9935
     * @return string
9936
     */
9937
    public static function getSessionListTabs($listType): string
9938
    {
9939
        $tabs = [
9940
            [
9941
                'content' => get_lang('All sessions'),
9942
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=all',
9943
            ],
9944
            [
9945
                'content' => get_lang('Active sessions'),
9946
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=active',
9947
            ],
9948
            [
9949
                'content' => get_lang('Closed sessions'),
9950
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=close',
9951
            ],
9952
            [
9953
                'content' => get_lang('Custom list'),
9954
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=custom',
9955
            ],
9956
            [
9957
                'content' => get_lang('Replication'),
9958
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=replication',
9959
            ],
9960
        ];
9961
        $default = null;
9962
        switch ($listType) {
9963
            case 'all':
9964
                $default = 1;
9965
                break;
9966
            case 'active':
9967
                $default = 2;
9968
                break;
9969
            case 'close':
9970
                $default = 3;
9971
                break;
9972
            case 'custom':
9973
                $default = 4;
9974
                break;
9975
            case 'replication':
9976
                $default = 5;
9977
                break;
9978
        }
9979
9980
        return Display::tabsOnlyLink($tabs, $default);
9981
    }
9982
9983
    /**
9984
     * Check if a session is followed by human resources manager.
9985
     *
9986
     * @param int $sessionId
9987
     * @param int $userId
9988
     *
9989
     * @return bool
9990
     */
9991
    public static function isSessionFollowedByDrh($sessionId, $userId)
9992
    {
9993
        $userId = (int) $userId;
9994
        $sessionId = (int) $sessionId;
9995
9996
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9997
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9998
9999
        if (api_is_multiple_url_enabled()) {
10000
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
10001
10002
            $sql = "SELECT s.id FROM $tblSession s
10003
                INNER JOIN $tblSessionRelUser sru ON (sru.session_id = s.id)
10004
                LEFT JOIN $tblSessionRelAccessUrl a ON (s.id = a.session_id)
10005
                WHERE
10006
                    sru.user_id = '$userId' AND
10007
                    sru.session_id = '$sessionId' AND
10008
                    sru.relation_type = '".Session::DRH."' AND
10009
                    access_url_id = ".api_get_current_access_url_id();
10010
        } else {
10011
            $sql = "SELECT s.id FROM $tblSession s
10012
                INNER JOIN $tblSessionRelUser sru ON sru.session_id = s.id
10013
                WHERE
10014
                    sru.user_id = '$userId' AND
10015
                    sru.session_id = '$sessionId' AND
10016
                    sru.relation_type = '".Session::DRH."'";
10017
        }
10018
10019
        $result = Database::query($sql);
10020
10021
        return Database::num_rows($result) > 0;
10022
    }
10023
10024
    /**
10025
     * Add a warning message when session is read-only mode.
10026
     */
10027
    public static function addFlashSessionReadOnly()
10028
    {
10029
        if (api_get_session_id() && !api_is_allowed_to_session_edit()) {
10030
            Display::addFlash(
10031
                Display::return_message(get_lang('The session is read only'), 'warning')
10032
            );
10033
        }
10034
    }
10035
10036
    public static function insertUsersInCourses(array $studentIds, array $courseIds, int $sessionId)
10037
    {
10038
        $session = api_get_session_entity($sessionId);
10039
10040
        foreach ($courseIds as $courseId) {
10041
            self::insertUsersInCourse($studentIds, $courseId, $sessionId, [], false);
10042
        }
10043
10044
        foreach ($studentIds as $studentId) {
10045
            $user = api_get_user_entity($studentId);
10046
10047
            $session->addUserInSession(Session::STUDENT, $user);
10048
        }
10049
    }
10050
10051
    /**
10052
     * @throws \Doctrine\ORM\Exception\ORMException
10053
     */
10054
    public static function insertUsersInCourse(
10055
        array $studentIds,
10056
        int $courseId,
10057
        int $sessionId,
10058
        array $relationInfo = [],
10059
        bool $updateSession = true,
10060
        bool $sendNotification = false
10061
    ) {
10062
        $em = Database::getManager();
10063
        $course = api_get_course_entity($courseId);
10064
        $session = api_get_session_entity($sessionId);
10065
10066
        $relationInfo = array_merge(['visibility' => 0, 'status' => Session::STUDENT], $relationInfo);
10067
10068
        $usersToInsert = [];
10069
        foreach ($studentIds as $studentId) {
10070
            $user = api_get_user_entity($studentId);
10071
            $session->addUserInCourse($relationInfo['status'], $user, $course)
10072
                ->setVisibility($relationInfo['visibility']);
10073
10074
            Event::logUserSubscribedInCourseSession($user, $course, $session);
10075
10076
            if ($updateSession) {
10077
                if (!$session->hasUserInSession($user, Session::STUDENT)) {
10078
                    $session->addUserInSession(Session::STUDENT, $user);
10079
                }
10080
            }
10081
10082
            $usersToInsert[] = $studentId;
10083
        }
10084
10085
        $em->persist($session);
10086
        $em->flush();
10087
10088
        if ($sendNotification && !empty($usersToInsert)) {
10089
            foreach ($usersToInsert as $userId) {
10090
                $user = api_get_user_entity($userId);
10091
                $courseTitle = $course->getTitle();
10092
                $sessionTitle = $session->getTitle();
10093
10094
                $subject = sprintf(get_lang('You have been enrolled in the course %s for the session %s'), $courseTitle, $sessionTitle);
10095
                $message = sprintf(
10096
                    get_lang('Hello %s, you have been enrolled in the course %s for the session %s.'),
10097
                    UserManager::formatUserFullName($user, true),
10098
                    $courseTitle,
10099
                    $sessionTitle
10100
                );
10101
10102
                MessageManager::send_message_simple(
10103
                    $userId,
10104
                    $subject,
10105
                    $message,
10106
                    api_get_user_id(),
10107
                    false,
10108
                    true
10109
                );
10110
            }
10111
        }
10112
    }
10113
10114
    public static function getCareersFromSession(int $sessionId): array
10115
    {
10116
        $extraFieldValueSession = new ExtraFieldValue('session');
10117
        $extraFieldValueCareer = new ExtraFieldValue('career');
10118
10119
        $value = $extraFieldValueSession->get_values_by_handler_and_field_variable($sessionId, 'careerid');
10120
        $careers = [];
10121
        if (isset($value['value']) && !empty($value['value'])) {
10122
            $careerList = str_replace(['[', ']'], '', $value['value']);
10123
            $careerList = explode(',', $careerList);
10124
10125
            $careerManager = new Career();
10126
            foreach ($careerList as $career) {
10127
                $careerIdValue = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
10128
                    'external_career_id',
10129
                    $career
10130
                );
10131
                if (isset($careerIdValue['item_id']) && !empty($careerIdValue['item_id'])) {
10132
                    $finalCareerId = $careerIdValue['item_id'];
10133
                    $careerInfo = $careerManager->get($finalCareerId);
10134
                    if (!empty($careerInfo)) {
10135
                        $careers[] = $careerInfo;
10136
                    }
10137
                }
10138
            }
10139
        }
10140
10141
        return $careers;
10142
    }
10143
10144
    public static function getCareerDiagramPerSessionList($sessionList, $userId)
10145
    {
10146
        if (empty($sessionList) || empty($userId)) {
10147
            return '';
10148
        }
10149
10150
        $userId = (int) $userId;
10151
        $content = Display::page_subheader(get_lang('Ongoing training'));
10152
        $content .= '
10153
           <script>
10154
            resizeIframe = function(iFrame) {
10155
                iFrame.height = iFrame.contentWindow.document.body.scrollHeight + 20;
10156
            }
10157
            </script>
10158
        ';
10159
        $careersAdded = [];
10160
        foreach ($sessionList as $sessionId) {
10161
            $visibility = api_get_session_visibility($sessionId, null, false, $userId);
10162
            if (SESSION_AVAILABLE === $visibility) {
10163
                $careerList = self::getCareersFromSession($sessionId);
10164
                if (empty($careerList)) {
10165
                    continue;
10166
                }
10167
                foreach ($careerList as $career) {
10168
                    $careerId = $career['id'];
10169
                    if (!in_array($careerId, $careersAdded)) {
10170
                        $careersAdded[] = $careerId;
10171
                        $careerUrl = api_get_path(WEB_CODE_PATH).'user/career_diagram.php?iframe=1&career_id='.$career['id'].'&user_id='.$userId;
10172
                        $content .= '
10173
                            <iframe
10174
                                onload="resizeIframe(this)"
10175
                                style="width:100%;"
10176
                                border="0"
10177
                                frameborder="0"
10178
                                scrolling="no"
10179
                                src="'.$careerUrl.'"
10180
                            ></iframe>';
10181
                    }
10182
                }
10183
            }
10184
        }
10185
10186
        return $content;
10187
    }
10188
10189
    private static function allowed(?Session $session = null): bool
10190
    {
10191
        if (api_is_platform_admin()) {
10192
            return true;
10193
        }
10194
10195
        if (null === $session) {
10196
            return false;
10197
        }
10198
10199
        $user = api_get_user_entity();
10200
10201
        if (api_is_session_admin() &&
10202
            'true' !== api_get_setting('session.allow_session_admins_to_manage_all_sessions')
10203
        ) {
10204
10205
            if (!$session->hasUserAsSessionAdmin($user)) {
10206
                return false;
10207
            }
10208
        }
10209
10210
        if (api_is_teacher() &&
10211
            'true' === api_get_setting('session.allow_teachers_to_create_sessions')
10212
        ) {
10213
            if (!$session->hasUserAsGeneralCoach($user))  {
10214
                return false;
10215
            }
10216
        }
10217
10218
        return true;
10219
    }
10220
10221
    /**
10222
     * Add classes (by their names) to a session.
10223
     *
10224
     * @param int   $sessionId
10225
     * @param array $classesNames
10226
     * @param bool  $deleteClassSessions Optional. Empty the session list for the usergroup (class)
10227
     */
10228
    private static function addClassesByName($sessionId, $classesNames, $deleteClassSessions = true)
10229
    {
10230
        if (!$classesNames) {
10231
            return;
10232
        }
10233
10234
        $usergroup = new UserGroupModel();
10235
10236
        foreach ($classesNames as $className) {
10237
            if (empty($className)) {
10238
                continue;
10239
            }
10240
10241
            $usergroup->subscribe_sessions_to_usergroup(
10242
                $usergroup->getIdByName($className),
10243
                [$sessionId],
10244
                $deleteClassSessions
10245
            );
10246
        }
10247
    }
10248
10249
    /**
10250
     * @param array $listA
10251
     * @param array $listB
10252
     *
10253
     * @return int
10254
     */
10255
    private static function compareCatSessionInfo($listA, $listB)
10256
    {
10257
        if ($listA['sessionName'] == $listB['sessionName']) {
10258
            return 0;
10259
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
10260
            return 1;
10261
        } else {
10262
            return -1;
10263
        }
10264
    }
10265
10266
    /**
10267
     * @param array $listA
10268
     * @param array $listB
10269
     *
10270
     * @return int
10271
     */
10272
    private static function compareBySessionName($listA, $listB)
10273
    {
10274
        if ('' == $listB['catSessionName']) {
10275
            return -1;
10276
        } elseif ('' == $listA['catSessionName']) {
10277
            return 1;
10278
        } elseif ($listA['catSessionName'] == $listB['catSessionName']) {
10279
            return 0;
10280
        } elseif ($listA['catSessionName'] > $listB['catSessionName']) {
10281
            return 1;
10282
        } else {
10283
            return -1;
10284
        }
10285
    }
10286
10287
    /**
10288
     * @param array $listA
10289
     * @param array $listB
10290
     *
10291
     * @return int
10292
     */
10293
    private static function compareByUserCourseCat($listA, $listB)
10294
    {
10295
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
10296
            return 0;
10297
        } elseif ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
10298
            return 1;
10299
        } else {
10300
            return -1;
10301
        }
10302
    }
10303
10304
    /**
10305
     * @param array $listA
10306
     * @param array $listB
10307
     *
10308
     * @return int
10309
     */
10310
    private static function compareByCourse($listA, $listB)
10311
    {
10312
        if ($listA['title'] == $listB['title']) {
10313
            return 0;
10314
        } elseif ($listA['title'] > $listB['title']) {
10315
            return 1;
10316
        } else {
10317
            return -1;
10318
        }
10319
    }
10320
10321
    public static function getGeneralCoachesIdForSession(int $sessionId): array
10322
    {
10323
        return api_get_session_entity($sessionId)
10324
            ->getGeneralCoaches()
10325
            ->map(fn(User $user) => $user->getId())
10326
            ->getValues();
10327
    }
10328
10329
    public static function getGeneralCoachesNamesForSession(int $sessionId): array
10330
    {
10331
        return api_get_session_entity($sessionId)
10332
            ->getGeneralCoaches()
10333
            ->map(fn(User $user) => $user->getFullname())
10334
            ->getValues();
10335
    }
10336
10337
    public static function sessionHasSessionAdmin(int $sessionId, int $userId): bool
10338
    {
10339
        $adminIds = api_get_session_entity($sessionId)
10340
            ->getSessionAdmins()
10341
            ->map(fn(User $user) => $user->getId())
10342
            ->getValues();
10343
10344
        return in_array($userId, $adminIds);
10345
    }
10346
10347
    /**
10348
     * Retrieves all user IDs associated with a session including coaches and students.
10349
     *
10350
     * @param int $sessionId The session ID.
10351
     * @return array An array of user IDs.
10352
     */
10353
    public static function getAllUserIdsInSession(int $sessionId): array
10354
    {
10355
        $users = [];
10356
        $session = api_get_session_entity($sessionId);
10357
        if ($session) {
10358
            $courses = $session->getCourses();
10359
            if (!empty($courses)) {
10360
                foreach ($courses as $sessionRelCourse) {
10361
                    $course = $sessionRelCourse->getCourse();
10362
                    $coachSubscriptions = $session->getSessionRelCourseRelUsersByStatus($course, Session::COURSE_COACH);
10363
                    foreach ($coachSubscriptions as $coachSubscription) {
10364
                        $users[]['user_id'] = $coachSubscription->getUser()->getId();
10365
                    }
10366
10367
                    $userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus($course, Session::STUDENT);
10368
                    foreach ($userCourseSubscriptions as $courseSubscription) {
10369
                        $users[]['user_id'] = $courseSubscription->getUser()->getId();
10370
                    }
10371
10372
                }
10373
            }
10374
10375
            $generalCoachesId = self::getGeneralCoachesIdForSession($sessionId);
10376
            if (!empty($generalCoachesId)) {
10377
                foreach ($generalCoachesId as $generalCoachId) {
10378
                    $users[]['user_id'] = $generalCoachId;
10379
                }
10380
            }
10381
        }
10382
10383
        return $users;
10384
    }
10385
10386
    /**
10387
     * Retrieves a list of parent sessions.
10388
     */
10389
    public static function getListOfParentSessions(): array
10390
    {
10391
        $sessions = [];
10392
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
10393
        $sql = "SELECT id, title FROM $tbl_session ORDER BY title";
10394
        $result = Database::query($sql);
10395
10396
        while ($row = Database::fetch_array($result)) {
10397
            $sessions[$row['id']] = $row['title'];
10398
        }
10399
10400
        return $sessions;
10401
    }
10402
10403
10404
    /**
10405
     * Method to export sessions data as CSV
10406
     */
10407
    public static function exportSessionsAsCSV(array $selectedSessions): void
10408
    {
10409
        $csvData = [];
10410
        $headersGenerated = false;
10411
        $csvHeaders = [];
10412
10413
        foreach ($selectedSessions as $sessionId) {
10414
            $courses = SessionManager::get_course_list_by_session_id($sessionId);
10415
10416
            if (!empty($courses)) {
10417
                foreach ($courses as $course) {
10418
                    $courseCode = $course['course_code'];
10419
                    $courseId = $course['id'];
10420
                    $studentList = CourseManager::get_student_list_from_course_code(
10421
                        $courseCode,
10422
                        true,
10423
                        $sessionId
10424
                    );
10425
10426
                    $userIds = array_keys($studentList);
10427
10428
                    [$generatedHeaders, $csvContent] = self::generateSessionCourseReportData($sessionId, $courseId, $userIds);
10429
10430
                    if (!$headersGenerated) {
10431
                        $csvHeaders = $generatedHeaders;
10432
                        $headersGenerated = true;
10433
                    }
10434
10435
                    foreach ($csvContent as $row) {
10436
                        $csvData[] = $row;
10437
                    }
10438
                }
10439
            }
10440
        }
10441
10442
        if (!empty($csvData)) {
10443
            array_unshift($csvData, $csvHeaders);
10444
            $filename = 'export_session_courses_reports_complete_' . date('Y-m-d_H-i-s') . '.csv';
10445
            Export::arrayToCsvSimple($csvData, $filename);
10446
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10447
        }
10448
    }
10449
10450
    /**
10451
     * Exports session data as a ZIP file with CSVs and sends it for download.
10452
     */
10453
    public static function exportSessionsAsZip(array $sessionList): void
10454
    {
10455
        $tempZipFile = api_get_path(SYS_ARCHIVE_PATH) . api_get_unique_id() . '.zip';
10456
        $tempDir = dirname($tempZipFile);
10457
10458
        if (!is_dir($tempDir) || !is_writable($tempDir)) {
10459
            exit("The directory for creating the ZIP file does not exist or lacks write permissions: $tempDir");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10460
        }
10461
10462
        $zip = new \ZipArchive();
10463
        if ($zip->open($tempZipFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
10464
            exit("Unable to open the ZIP file for writing: $tempZipFile");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10465
        }
10466
10467
        foreach ($sessionList as $sessionItemId) {
10468
            $courses = SessionManager::get_course_list_by_session_id($sessionItemId);
10469
10470
            if (!empty($courses)) {
10471
                foreach ($courses as $course) {
10472
                    $courseCode = $course['course_code'];
10473
                    $courseId = $course['id'];
10474
                    $studentList = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionItemId);
10475
                    $userIds = array_keys($studentList);
10476
10477
                    [$csvHeaders, $csvContent] = self::generateSessionCourseReportData($sessionItemId, $courseId, $userIds);
10478
                    array_unshift($csvContent, $csvHeaders);
10479
10480
                    $sessionInfo = api_get_session_info($sessionItemId);
10481
                    $courseInfo = api_get_course_info_by_id($courseId);
10482
                    $csvFileName = $sessionInfo['name'] . '_' . $courseInfo['name'] . '.csv';
10483
10484
                    $csvFilePath = Export::arrayToCsvSimple($csvContent, $csvFileName, true);
10485
10486
                    if ($csvFilePath && file_exists($csvFilePath)) {
10487
                        $zip->addFile($csvFilePath, $csvFileName);
10488
                    }
10489
                }
10490
            }
10491
        }
10492
10493
        if (!$zip->close()) {
10494
            exit("Could not close the ZIP file correctly.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10495
        }
10496
10497
        if (file_exists($tempZipFile)) {
10498
            DocumentManager::file_send_for_download($tempZipFile, true);
10499
            unlink($tempZipFile);
10500
        } else {
10501
            exit("The ZIP file was not created correctly.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10502
        }
10503
    }
10504
10505
    private static function generateSessionCourseReportData($sessionId, $courseId, $userIds): array
10506
    {
10507
        $em = Database::getManager();
10508
        $sessionRepository = $em->getRepository(Session::class);
10509
        $session = $sessionRepository->find($sessionId);
10510
10511
        if (!$session instanceof Session) {
10512
            throw new \InvalidArgumentException("Invalid session object for session ID $sessionId");
10513
        }
10514
10515
        $courseInfo = api_get_course_info_by_id($courseId);
10516
        $courseCode = $courseInfo['code'];
10517
10518
        $csvHeaders = [
10519
            get_lang('Session name'),
10520
            get_lang('Session access dates'),
10521
            get_lang('Session display dates'),
10522
            get_lang('Course name'),
10523
            get_lang('Official code'),
10524
            get_lang('First name'),
10525
            get_lang('Last name'),
10526
            get_lang('Login'),
10527
            get_lang('Training time'),
10528
            get_lang('Course progress'),
10529
            get_lang('Exercise progress'),
10530
            get_lang('Exercise average'),
10531
            get_lang('Score'),
10532
            get_lang('Score') . ' - ' . get_lang('Best attempt'),
10533
            get_lang('Student_publication'),
10534
            get_lang('Messages'),
10535
            get_lang('Classes'),
10536
            get_lang('Registration date'),
10537
            get_lang('First login in course'),
10538
            get_lang('Latest login in course'),
10539
        ];
10540
10541
        $csvData = TrackingCourseLog::getUserData(
10542
            null,
10543
            count($userIds),
10544
            null,
10545
            null,
10546
            [],
10547
            true,
10548
            true,
10549
            $courseCode,
10550
            $sessionId,
10551
            true,
10552
            $userIds
10553
        );
10554
10555
        $rawCsvContent = ChamiloSession::read('csv_content');
10556
10557
        if (empty($rawCsvContent)) {
10558
            throw new \RuntimeException("No CSV content found in session for course $courseCode and session $sessionId.");
10559
        }
10560
10561
        $csvContent = [];
10562
        foreach ($rawCsvContent as $row) {
10563
            $alignedRow = [
10564
                $row['session_name'] ?? '',
10565
                $row['session_startdate'] ?? '',
10566
                $row['session_enddate'] ?? '',
10567
                $row['course_name'] ?? '',
10568
                $row['official_code'] ?? '',
10569
                $row['firstname'] ?? '',
10570
                $row['lastname'] ?? '',
10571
                $row['username'] ?? '',
10572
                $row['time'] ?? '',
10573
                $row['average_progress'] ?? '',
10574
                $row['exercise_progress'] ?? '',
10575
                $row['exercise_average'] ?? '',
10576
                $row['student_score'] ?? '',
10577
                $row['student_score_best'] ?? '',
10578
                $row['count_assignments'] ?? '',
10579
                $row['count_messages'] ?? '',
10580
                $row['classes'] ?? '',
10581
                $row['registered_at'] ?? '',
10582
                $row['first_connection'] ?? '',
10583
                $row['last_connection'] ?? '',
10584
            ];
10585
            $csvContent[] = $alignedRow;
10586
        }
10587
10588
        return [$csvHeaders, $csvContent];
10589
    }
10590
}
10591