Passed
Push — dependabot/npm_and_yarn/cross-... ( ad80c0...c9e4a1 )
by
unknown
15:20 queued 04:46
created

SessionManager::generateSessionCourseReportData()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 84
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 67
nc 4
nop 3
dl 0
loc 84
rs 8.72
c 0
b 0
f 0

How to fix   Long Method   

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