Passed
Pull Request — master (#5886)
by
unknown
08:45
created

SessionManager::insertUsersInCourse()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 55
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 34
nc 12
nop 6
dl 0
loc 55
rs 8.4426
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
            true,
2620
            true
2621
        );
2622
    }
2623
2624
    /**
2625
     * Unsubscribe user from session.
2626
     *
2627
     * @param int Session id
2628
     * @param int User id
2629
     *
2630
     * @return bool True in case of success, false in case of error
2631
     */
2632
    public static function unsubscribe_user_from_session($session_id, $user_id)
2633
    {
2634
        $session_id = (int) $session_id;
2635
        $user_id = (int) $user_id;
2636
2637
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2638
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2639
2640
        $sql = "DELETE FROM $tbl_session_rel_user
2641
                WHERE
2642
                    session_id = $session_id AND
2643
                    user_id = $user_id ";
2644
        Database::query($sql);
2645
2646
        // Update number of users
2647
        $sql = "UPDATE $tbl_session
2648
                SET nbr_users = nbr_users - 1
2649
                WHERE id = $session_id ";
2650
        Database::query($sql);
2651
2652
        Event::addEvent(
2653
            LOG_SESSION_DELETE_USER,
2654
            LOG_USER_ID,
2655
            $user_id,
2656
            api_get_utc_datetime(),
2657
            api_get_user_id(),
2658
            null,
2659
            $session_id
2660
        );
2661
2662
        // Get the list of courses related to this session
2663
        $course_list = self::get_course_list_by_session_id($session_id);
2664
        if (!empty($course_list)) {
2665
            foreach ($course_list as $course) {
2666
                self::unSubscribeUserFromCourseSession($user_id, $course['id'], $session_id);
2667
            }
2668
        }
2669
2670
        return true;
2671
    }
2672
2673
    /**
2674
     * @param int $user_id
2675
     * @param int $courseId
2676
     * @param int $session_id
2677
     */
2678
    public static function unSubscribeUserFromCourseSession($user_id, $courseId, $session_id)
2679
    {
2680
        $user_id = (int) $user_id;
2681
        $courseId = (int) $courseId;
2682
        $session_id = (int) $session_id;
2683
2684
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2685
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2686
2687
        // Delete user from course
2688
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2689
                WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2690
        $result = Database::query($sql);
2691
2692
        if (Database::affected_rows($result)) {
2693
            // Update number of users in this relation
2694
            $sql = "UPDATE $tbl_session_rel_course SET
2695
                    nbr_users = nbr_users - 1
2696
                    WHERE session_id = $session_id AND c_id = $courseId";
2697
            Database::query($sql);
2698
        }
2699
2700
        Event::addEvent(
2701
            LOG_SESSION_DELETE_USER_COURSE,
2702
            LOG_USER_ID,
2703
            $user_id,
2704
            api_get_utc_datetime(),
2705
            api_get_user_id(),
2706
            $courseId,
2707
            $session_id
2708
        );
2709
    }
2710
2711
    /**
2712
     * Subscribes courses to the given session and optionally (default)
2713
     * unsubscribe previous users.
2714
     *
2715
     * @author Carlos Vargas from existing code
2716
     *
2717
     * @param int   $sessionId
2718
     * @param array $courseList                     List of courses int ids
2719
     * @param bool  $removeExistingCoursesWithUsers Whether to unsubscribe
2720
     *                                              existing courses and users (true, default) or not (false)
2721
     * @param bool  $copyEvaluation                 from base course to session course
2722
     * @param bool  $copyCourseTeachersAsCoach
2723
     * @param bool  $importAssignments
2724
     *
2725
     * @throws Exception
2726
     *
2727
     * @return bool False on failure, true otherwise
2728
     * */
2729
    public static function add_courses_to_session(
2730
        $sessionId,
2731
        $courseList,
2732
        $removeExistingCoursesWithUsers = true,
2733
        $copyEvaluation = false,
2734
        $copyCourseTeachersAsCoach = false,
2735
        $importAssignments = false
2736
    ) {
2737
        $sessionId = (int) $sessionId;
2738
2739
        if (empty($sessionId) || empty($courseList)) {
2740
            return false;
2741
        }
2742
2743
        $session = api_get_session_entity($sessionId);
2744
2745
        if (!$session) {
2746
            return false;
2747
        }
2748
        $sessionVisibility = $session->getVisibility();
2749
2750
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2751
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2752
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2753
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2754
2755
        // Get list of courses subscribed to this session
2756
        $sql = "SELECT c_id
2757
                FROM $tbl_session_rel_course
2758
                WHERE session_id = $sessionId";
2759
        $rs = Database::query($sql);
2760
        $existingCourses = Database::store_result($rs);
2761
        $nbr_courses = count($existingCourses);
2762
2763
        // Get list of users subscribed to this session
2764
        $sql = "SELECT user_id
2765
                FROM $tbl_session_rel_user
2766
                WHERE
2767
                    session_id = $sessionId AND
2768
                    relation_type = ".Session::STUDENT;
2769
        $result = Database::query($sql);
2770
        $user_list = Database::store_result($result);
2771
2772
        // Remove existing courses from the session.
2773
        if (true === $removeExistingCoursesWithUsers && !empty($existingCourses)) {
2774
            foreach ($existingCourses as $existingCourse) {
2775
                if (!in_array($existingCourse['c_id'], $courseList)) {
2776
                    $sql = "DELETE FROM $tbl_session_rel_course
2777
                            WHERE
2778
                                c_id = ".$existingCourse['c_id']." AND
2779
                                session_id = $sessionId";
2780
                    Database::query($sql);
2781
2782
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2783
                            WHERE
2784
                                c_id = ".$existingCourse['c_id']." AND
2785
                                session_id = $sessionId";
2786
                    Database::query($sql);
2787
2788
                    Event::addEvent(
2789
                        LOG_SESSION_DELETE_COURSE,
2790
                        LOG_COURSE_ID,
2791
                        $existingCourse['c_id'],
2792
                        api_get_utc_datetime(),
2793
                        api_get_user_id(),
2794
                        $existingCourse['c_id'],
2795
                        $sessionId
2796
                    );
2797
2798
                    CourseManager::remove_course_ranking(
2799
                        $existingCourse['c_id'],
2800
                        $sessionId
2801
                    );
2802
                    $nbr_courses--;
2803
                }
2804
            }
2805
        }
2806
2807
        // Pass through the courses list we want to add to the session
2808
        foreach ($courseList as $courseId) {
2809
            $courseInfo = api_get_course_info_by_id($courseId);
2810
2811
            // If course doesn't exist continue!
2812
            if (empty($courseInfo)) {
2813
                continue;
2814
            }
2815
2816
            $exists = false;
2817
            // check if the course we want to add is already subscribed
2818
            foreach ($existingCourses as $existingCourse) {
2819
                if ($courseId == $existingCourse['c_id']) {
2820
                    $exists = true;
2821
                }
2822
            }
2823
2824
            if (!$exists) {
2825
                // Copy gradebook categories and links (from base course)
2826
                // to the new course session
2827
                if ($copyEvaluation) {
2828
                    $cats = Category::load(null, null, $courseId);
2829
                    if (!empty($cats)) {
2830
                        $sessionCategory = Category:: load(
2831
                            null,
2832
                            null,
2833
                            $courseId,
2834
                            null,
2835
                            null,
2836
                            $sessionId,
2837
                            null
2838
                        );
2839
2840
                        // @todo remove commented code
2841
                        if (empty($sessionCategory)) {
2842
                            // There is no category for this course+session, so create one
2843
                            $cat = new Category();
2844
                            $sessionName = $session->getTitle();
2845
                            $cat->set_name($courseInfo['code'].' - '.get_lang('Session').' '.$sessionName);
2846
                            $cat->set_session_id($sessionId);
2847
                            $cat->setCourseId($courseId);
2848
                            $cat->set_description(null);
2849
                            //$cat->set_user_id($stud_id);
2850
                            $cat->set_parent_id(0);
2851
                            $cat->set_weight(100);
2852
                            $cat->set_visible(0);
2853
                            $cat->set_certificate_min_score(75);
2854
                            $cat->add();
2855
                            $sessionGradeBookCategoryId = $cat->get_id();
2856
                        } else {
2857
                            if (!empty($sessionCategory[0])) {
2858
                                $sessionGradeBookCategoryId = $sessionCategory[0]->get_id();
2859
                            }
2860
                        }
2861
2862
                        $categoryIdList = [];
2863
                        /** @var Category $cat */
2864
                        foreach ($cats as $cat) {
2865
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2866
                        }
2867
2868
                        $newCategoryIdList = [];
2869
                        foreach ($cats as $cat) {
2870
                            $links = $cat->get_links(
2871
                                null,
2872
                                false,
2873
                                $courseId,
2874
                                $sessionId
2875
                            );
2876
2877
                            //$cat->set_session_id($sessionId);
2878
                            //$oldCategoryId = $cat->get_id();
2879
                            //$newId = $cat->add();
2880
                            //$newCategoryIdList[$oldCategoryId] = $newId;
2881
                            //$parentId = $cat->get_parent_id();
2882
2883
                            /*if (!empty($parentId)) {
2884
                                $newParentId = $newCategoryIdList[$parentId];
2885
                                $cat->set_parent_id($newParentId);
2886
                                $cat->save();
2887
                            }*/
2888
2889
                            if (!empty($links)) {
2890
                                /** @var AbstractLink $link */
2891
                                foreach ($links as $link) {
2892
                                    //$newCategoryId = $newCategoryIdList[$link->get_category_id()];
2893
                                    $link->set_category_id($sessionGradeBookCategoryId);
2894
                                    $link->add();
2895
                                }
2896
                            }
2897
2898
                            $evaluationList = $cat->get_evaluations(
2899
                                null,
2900
                                false,
2901
                                $courseId,
2902
                                $sessionId
2903
                            );
2904
2905
                            if (!empty($evaluationList)) {
2906
                                /** @var Evaluation $evaluation */
2907
                                foreach ($evaluationList as $evaluation) {
2908
                                    //$evaluationId = $newCategoryIdList[$evaluation->get_category_id()];
2909
                                    $evaluation->set_category_id($sessionGradeBookCategoryId);
2910
                                    $evaluation->add();
2911
                                }
2912
                            }
2913
                        }
2914
2915
                        // Create
2916
                        DocumentManager::generateDefaultCertificate(
2917
                            $courseInfo,
2918
                            true,
2919
                            $sessionId
2920
                        );
2921
                    }
2922
                }
2923
2924
                if ($importAssignments) {
2925
                    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2926
                    $sql = " SELECT * FROM $workTable
2927
                             WHERE active = 1 AND
2928
                                   c_id = $courseId AND
2929
                                   parent_id = 0 AND
2930
                                   (session_id IS NULL OR session_id = 0)";
2931
                    $result = Database::query($sql);
2932
                    $workList = Database::store_result($result, 'ASSOC');
2933
2934
                    foreach ($workList as $work) {
2935
                        $values = [
2936
                            'work_title' => $work['title'],
2937
                            'new_dir' => $work['url'].'_session_'.$sessionId,
2938
                            'description' => $work['description'],
2939
                            'qualification' => $work['qualification'],
2940
                            'allow_text_assignment' => $work['allow_text_assignment'],
2941
                        ];
2942
                        // @todo add addDir with resources
2943
                        /*addDir(
2944
                            $values,
2945
                            api_get_user_id(),
2946
                            $courseInfo,
2947
                            0,
2948
                            $sessionId
2949
                        );*/
2950
                    }
2951
                }
2952
                // If the course isn't subscribed yet
2953
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2954
                        VALUES ($sessionId, $courseId, 0, 0)";
2955
                Database::query($sql);
2956
2957
                Event::addEvent(
2958
                    LOG_SESSION_ADD_COURSE,
2959
                    LOG_COURSE_ID,
2960
                    $courseId,
2961
                    api_get_utc_datetime(),
2962
                    api_get_user_id(),
2963
                    $courseId,
2964
                    $sessionId
2965
                );
2966
2967
                // We add the current course in the existing courses array,
2968
                // to avoid adding another time the current course
2969
                $existingCourses[] = ['c_id' => $courseId];
2970
                $nbr_courses++;
2971
2972
                // Subscribe all the users from the session to this course inside the session
2973
                self::insertUsersInCourse(
2974
                    array_column($user_list, 'user_id'),
2975
                    $courseId,
2976
                    $sessionId,
2977
                    ['visibility' => $sessionVisibility],
2978
                    false
2979
                );
2980
            }
2981
2982
            if ($copyCourseTeachersAsCoach) {
2983
                $teachers = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
2984
                if (!empty($teachers)) {
2985
                    foreach ($teachers as $teacher) {
2986
                        self::updateCoaches(
2987
                            $sessionId,
2988
                            $courseId,
2989
                            [$teacher['user_id']],
2990
                            false
2991
                        );
2992
                    }
2993
                }
2994
            }
2995
        }
2996
2997
        $sql = "UPDATE $tbl_session SET nbr_courses = $nbr_courses WHERE id = $sessionId";
2998
        Database::query($sql);
2999
3000
        return true;
3001
    }
3002
3003
    /**
3004
     * Unsubscribe course from a session.
3005
     *
3006
     * @param int $session_id
3007
     * @param int $course_id
3008
     *
3009
     * @return bool True in case of success, false otherwise
3010
     */
3011
    public static function unsubscribe_course_from_session($session_id, $course_id)
3012
    {
3013
        $session_id = (int) $session_id;
3014
        $course_id = (int) $course_id;
3015
3016
        if (empty($course_id) || empty($session_id)) {
3017
            return false;
3018
        }
3019
3020
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3021
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3022
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3023
3024
        // Unsubscribe course.
3025
        $sql = "DELETE FROM $tbl_session_rel_course
3026
                WHERE c_id = $course_id AND session_id = $session_id";
3027
        $result = Database::query($sql);
3028
        $nb_affected = Database::affected_rows($result);
3029
3030
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
3031
                WHERE c_id = $course_id AND session_id = $session_id";
3032
        Database::query($sql);
3033
3034
        Event::addEvent(
3035
            LOG_SESSION_DELETE_COURSE,
3036
            LOG_COURSE_ID,
3037
            $course_id,
3038
            api_get_utc_datetime(),
3039
            api_get_user_id(),
3040
            $course_id,
3041
            $session_id
3042
        );
3043
3044
        if ($nb_affected > 0) {
3045
            // Update number of courses in the session
3046
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
3047
                    WHERE id = $session_id";
3048
            Database::query($sql);
3049
3050
            return true;
3051
        }
3052
3053
        return false;
3054
    }
3055
3056
    /**
3057
     * Creates a new extra field for a given session.
3058
     *
3059
     * @param string $variable    Field's internal variable name
3060
     * @param int    $fieldType   Field's type
3061
     * @param string $displayText Field's language var name
3062
     * @param string $default     Field's default value
3063
     *
3064
     * @return int new extra field id
3065
     */
3066
    public static function create_session_extra_field(
3067
        $variable,
3068
        $valueType,
3069
        $displayText,
3070
        $default = ''
3071
    ) {
3072
        $extraField = new ExtraFieldModel('session');
3073
        $params = [
3074
            'variable' => $variable,
3075
            'value_type' => $valueType,
3076
            'display_text' => $displayText,
3077
            'default_value' => $default,
3078
        ];
3079
3080
        return $extraField->save($params);
3081
    }
3082
3083
    /**
3084
     * Update an extra field value for a given session.
3085
     *
3086
     * @param int    $sessionId Session ID
3087
     * @param string $variable  Field variable name
3088
     * @param string $value     Optional. Default field value
3089
     *
3090
     * @return bool|int An integer when register a new extra field. And boolean when update the extrafield
3091
     */
3092
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
3093
    {
3094
        $extraFieldValue = new ExtraFieldValue('session');
3095
        $params = [
3096
            'item_id' => $sessionId,
3097
            'variable' => $variable,
3098
            'value' => $value,
3099
        ];
3100
3101
        return $extraFieldValue->save($params);
3102
    }
3103
3104
    /**
3105
     * Checks the relationship between a session and a course.
3106
     *
3107
     * @param int $session_id
3108
     * @param int $courseId
3109
     *
3110
     * @return bool returns TRUE if the session and the course are related, FALSE otherwise
3111
     * */
3112
    public static function relation_session_course_exist($session_id, $courseId)
3113
    {
3114
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3115
        $return_value = false;
3116
        $sql = "SELECT c_id FROM $tbl_session_course
3117
                WHERE
3118
                  session_id = ".intval($session_id)." AND
3119
                  c_id = ".intval($courseId);
3120
        $result = Database::query($sql);
3121
        $num = Database::num_rows($result);
3122
        if ($num > 0) {
3123
            $return_value = true;
3124
        }
3125
3126
        return $return_value;
3127
    }
3128
3129
    /**
3130
     * Get the session information by name.
3131
     *
3132
     * @param string $name
3133
     *
3134
     * @return mixed false if the session does not exist, array if the session exist
3135
     */
3136
    public static function get_session_by_name($name)
3137
    {
3138
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3139
        $name = Database::escape_string(trim($name));
3140
        if (empty($name)) {
3141
            return false;
3142
        }
3143
3144
        $sql = 'SELECT *
3145
		        FROM '.$tbl_session.'
3146
		        WHERE title = "'.$name.'"';
3147
        $result = Database::query($sql);
3148
        $num = Database::num_rows($result);
3149
        if ($num > 0) {
3150
            return Database::fetch_array($result);
3151
        } else {
3152
            return false;
3153
        }
3154
    }
3155
3156
    /**
3157
     * @param int $sessionId
3158
     * @param int $name
3159
     *
3160
     * @return bool
3161
     */
3162
    public static function sessionNameExistBesidesMySession($sessionId, $name)
3163
    {
3164
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
3165
        $name = Database::escape_string(trim($name));
3166
        $sessionId = (int) $sessionId;
3167
3168
        if (empty($name)) {
3169
            return false;
3170
        }
3171
3172
        $sql = "SELECT *
3173
		        FROM $table
3174
		        WHERE title = '$name' AND id <> $sessionId ";
3175
        $result = Database::query($sql);
3176
        $num = Database::num_rows($result);
3177
        if ($num > 0) {
3178
            return true;
3179
        }
3180
3181
        return false;
3182
    }
3183
3184
    /**
3185
     * Create a session category.
3186
     *
3187
     * @author Jhon Hinojosa <[email protected]>, from existing code
3188
     *
3189
     * @param string        name
3190
     * @param int        year_start
3191
     * @param int        month_start
3192
     * @param int        day_start
3193
     * @param int        year_end
3194
     * @param int        month_end
3195
     * @param int        day_end
3196
     *
3197
     * @return int session ID
3198
     * */
3199
    public static function create_category_session(
3200
        $sname,
3201
        $syear_start,
3202
        $smonth_start,
3203
        $sday_start,
3204
        $syear_end,
3205
        $smonth_end,
3206
        $sday_end
3207
    ) {
3208
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3209
        $name = trim($sname);
3210
        $year_start = intval($syear_start);
3211
        $month_start = intval($smonth_start);
3212
        $day_start = intval($sday_start);
3213
        $year_end = intval($syear_end);
3214
        $month_end = intval($smonth_end);
3215
        $day_end = intval($sday_end);
3216
3217
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3218
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3219
3220
        if (empty($name)) {
3221
            $msg = get_lang('Please give a name to the sessions category');
3222
3223
            return $msg;
3224
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3225
            $msg = get_lang('Invalid start date was given.');
3226
3227
            return $msg;
3228
        } elseif (!$month_end && !$day_end && !$year_end) {
3229
            $date_end = '';
3230
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3231
            $msg = get_lang('Invalid end date was given.');
3232
3233
            return $msg;
3234
        } elseif ($date_start >= $date_end) {
3235
            $msg = get_lang('The first date should be before the end date');
3236
3237
            return $msg;
3238
        }
3239
3240
        $access_url_id = api_get_current_access_url_id();
3241
        $params = [
3242
            'title' => $name,
3243
            'date_start' => $date_start,
3244
            'access_url_id' => $access_url_id,
3245
        ];
3246
3247
        if (!empty($date_end)) {
3248
            $params['date_end'] = $date_end;
3249
        }
3250
3251
        $id = Database::insert($tbl_session_category, $params);
3252
3253
        // Add event to system log
3254
        $user_id = api_get_user_id();
3255
        Event::addEvent(
3256
            LOG_SESSION_CATEGORY_CREATE,
3257
            LOG_SESSION_CATEGORY_ID,
3258
            $id,
3259
            api_get_utc_datetime(),
3260
            $user_id
3261
        );
3262
3263
        return $id;
3264
    }
3265
3266
    /**
3267
     * Edit a sessions category.
3268
     *
3269
     * @author Jhon Hinojosa <[email protected]>,from existing code
3270
     *
3271
     * @param int        id
3272
     * @param string        name
3273
     * @param int        year_start
3274
     * @param int        month_start
3275
     * @param int        day_start
3276
     * @param int        year_end
3277
     * @param int        month_end
3278
     * @param int        day_end
3279
     *
3280
     * @return bool
3281
     *              The parameter id is a primary key
3282
     * */
3283
    public static function edit_category_session(
3284
        $id,
3285
        $sname,
3286
        $syear_start,
3287
        $smonth_start,
3288
        $sday_start,
3289
        $syear_end,
3290
        $smonth_end,
3291
        $sday_end
3292
    ) {
3293
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3294
        $name = trim($sname);
3295
        $year_start = intval($syear_start);
3296
        $month_start = intval($smonth_start);
3297
        $day_start = intval($sday_start);
3298
        $year_end = intval($syear_end);
3299
        $month_end = intval($smonth_end);
3300
        $day_end = intval($sday_end);
3301
        $id = intval($id);
3302
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3303
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3304
3305
        if (empty($name)) {
3306
            $msg = get_lang('Please give a name to the sessions category');
3307
3308
            return $msg;
3309
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3310
            $msg = get_lang('Invalid start date was given.');
3311
3312
            return $msg;
3313
        } elseif (!$month_end && !$day_end && !$year_end) {
3314
            $date_end = null;
3315
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3316
            $msg = get_lang('Invalid end date was given.');
3317
3318
            return $msg;
3319
        } elseif ($date_start >= $date_end) {
3320
            $msg = get_lang('The first date should be before the end date');
3321
3322
            return $msg;
3323
        }
3324
        if (null != $date_end) {
3325
            $sql = "UPDATE $tbl_session_category
3326
                    SET
3327
                        title = '".Database::escape_string($name)."',
3328
                        date_start = '$date_start' ,
3329
                        date_end = '$date_end'
3330
                    WHERE id= $id";
3331
        } else {
3332
            $sql = "UPDATE $tbl_session_category SET
3333
                        title = '".Database::escape_string($name)."',
3334
                        date_start = '$date_start',
3335
                        date_end = NULL
3336
                    WHERE id= $id";
3337
        }
3338
        $result = Database::query($sql);
3339
3340
        return $result ? true : false;
3341
    }
3342
3343
    /**
3344
     * Delete sessions categories.
3345
     *
3346
     * @param array|int $categoryId
3347
     * @param bool      $deleteSessions Optional. Include delete session.
3348
     * @param bool      $fromWs         Optional. True if the function is called by a webservice, false otherwise.
3349
     *
3350
     * @return bool Nothing, or false on error
3351
     *              The parameters is a array to delete sessions
3352
     *
3353
     * @author Jhon Hinojosa <[email protected]>, from existing code
3354
     */
3355
    public static function delete_session_category($categoryId, $deleteSessions = false, $fromWs = false)
3356
    {
3357
        $tblSessionCategory = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3358
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
3359
3360
        if (is_array($categoryId)) {
3361
            $categoryId = array_map('intval', $categoryId);
3362
        } else {
3363
            $categoryId = [(int) $categoryId];
3364
        }
3365
3366
        $categoryId = implode(', ', $categoryId);
3367
3368
        if ($deleteSessions) {
3369
            $sql = "SELECT id FROM $tblSession WHERE session_category_id IN ($categoryId)";
3370
            $result = Database::query($sql);
3371
            while ($rows = Database::fetch_array($result)) {
3372
                $sessionId = $rows['id'];
3373
                self::delete($sessionId, $fromWs);
3374
            }
3375
        } else {
3376
            $sql = "UPDATE $tblSession SET session_category_id = NULL WHERE session_category_id IN ($categoryId)";
3377
            Database::query($sql);
3378
        }
3379
3380
        $sql = "DELETE FROM $tblSessionCategory WHERE id IN ($categoryId)";
3381
        Database::query($sql);
3382
3383
        // Add event to system log
3384
        Event::addEvent(
3385
            LOG_SESSION_CATEGORY_DELETE,
3386
            LOG_SESSION_CATEGORY_ID,
3387
            $categoryId,
3388
            api_get_utc_datetime(),
3389
            api_get_user_id()
3390
        );
3391
3392
        return true;
3393
    }
3394
3395
    /**
3396
     * Get a list of sessions of which the given conditions match with an = 'cond'.
3397
     *
3398
     * @param array $conditions          a list of condition example :
3399
     *                                   array('status' => STUDENT) or
3400
     *                                   array('s.title' => array('operator' => 'LIKE', value = '%$needle%'))
3401
     * @param array $order_by            a list of fields on which sort
3402
     * @param int   $urlId
3403
     * @param array $onlyThisSessionList
3404
     *
3405
     * @return array an array with all sessions of the platform
3406
     *
3407
     * @todo   optional course code parameter, optional sorting parameters...
3408
     */
3409
    public static function get_sessions_list(
3410
        $conditions = [],
3411
        $order_by = [],
3412
        $from = null,
3413
        $to = null,
3414
        $urlId = 0,
3415
        $onlyThisSessionList = []
3416
    ) {
3417
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3418
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3419
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
3420
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3421
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3422
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
3423
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
3424
        $return_array = [];
3425
3426
        $sql_query = " SELECT
3427
                    DISTINCT(s.id),
3428
                    s.title,
3429
                    s.nbr_courses,
3430
                    s.access_start_date,
3431
                    s.access_end_date,
3432
                    sc.title as category_name,
3433
                    s.promotion_id
3434
				FROM $session_table s
3435
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
3436
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
3437
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
3438
				INNER JOIN $course_table c ON sco.c_id = c.id
3439
				WHERE ar.access_url_id = $urlId ";
3440
3441
        $availableFields = [
3442
            's.id',
3443
            's.title',
3444
            'c.id',
3445
        ];
3446
3447
        $availableOperator = [
3448
            'like',
3449
            '>=',
3450
            '<=',
3451
            '=',
3452
        ];
3453
3454
        if (count($conditions) > 0) {
3455
            foreach ($conditions as $field => $options) {
3456
                $operator = strtolower($options['operator']);
3457
                $value = Database::escape_string($options['value']);
3458
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
3459
                    $sql_query .= ' AND '.$field." $operator '".$value."'";
3460
                }
3461
            }
3462
        }
3463
3464
        if (!empty($onlyThisSessionList)) {
3465
            $onlyThisSessionList = array_map('intval', $onlyThisSessionList);
3466
            $onlyThisSessionList = implode("','", $onlyThisSessionList);
3467
            $sql_query .= " AND s.id IN ('$onlyThisSessionList') ";
3468
        }
3469
3470
        $orderAvailableList = ['title'];
3471
        if (count($order_by) > 0) {
3472
            $order = null;
3473
            $direction = null;
3474
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
3475
                $order = $order_by[0];
3476
            }
3477
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), ['desc', 'asc'])) {
3478
                $direction = $order_by[1];
3479
            }
3480
3481
            if (!empty($order)) {
3482
                $sql_query .= " ORDER BY $order $direction ";
3483
            }
3484
        }
3485
3486
        if (!is_null($from) && !is_null($to)) {
3487
            $to = (int) $to;
3488
            $from = (int) $from;
3489
            $sql_query .= "LIMIT $from, $to";
3490
        }
3491
3492
        $sql_result = Database::query($sql_query);
3493
        if (Database::num_rows($sql_result) > 0) {
3494
            while ($result = Database::fetch_array($sql_result)) {
3495
                $return_array[$result['id']] = $result;
3496
            }
3497
        }
3498
3499
        return $return_array;
3500
    }
3501
3502
    /**
3503
     * Get the session category information by id.
3504
     *
3505
     * @param string session category ID
3506
     *
3507
     * @return mixed false if the session category does not exist, array if the session category exists
3508
     */
3509
    public static function get_session_category($id)
3510
    {
3511
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3512
        $id = (int) $id;
3513
        $sql = "SELECT id, title, date_start, date_end
3514
                FROM $table
3515
                WHERE id= $id";
3516
        $result = Database::query($sql);
3517
        $num = Database::num_rows($result);
3518
        if ($num > 0) {
3519
            return Database::fetch_array($result);
3520
        } else {
3521
            return false;
3522
        }
3523
    }
3524
3525
    /**
3526
     * Get Hot Sessions (limit 8).
3527
     *
3528
     * @return array with sessions
3529
     */
3530
    public static function getHotSessions()
3531
    {
3532
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3533
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3534
        $tbl_users = Database::get_main_table(TABLE_MAIN_USER);
3535
        $tbl_extra_fields = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3536
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3537
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
3538
3539
        $extraField = new ExtraFieldModel('session');
3540
        $field = $extraField->get_handler_field_info_by_field_variable('image');
3541
3542
        $sql = "SELECT
3543
                s.id,
3544
                s.title,
3545
                s.session_category_id,
3546
                c.title as category_name,
3547
                s.description,
3548
                s.nbr_users as users,
3549
				(SELECT COUNT(*) FROM $tbl_lp WHERE session_id = s.id) as lessons ";
3550
        if (false !== $field) {
3551
            $fieldId = $field['id'];
3552
            $sql .= ",(SELECT value FROM $tbl_extra_fields WHERE field_id = $fieldId AND item_id = s.id) as image ";
3553
        }
3554
        $sql .= " FROM $tbl_session s
3555
                LEFT JOIN $tbl_session_category c
3556
                    ON s.session_category_id = c.id
3557
                ORDER BY 8 DESC
3558
                LIMIT 8";
3559
        $result = Database::query($sql);
3560
3561
        if (Database::num_rows($result) > 0) {
3562
            $plugin = BuyCoursesPlugin::create();
3563
            $checker = $plugin->isEnabled();
3564
            $sessions = [];
3565
            while ($row = Database::fetch_assoc($result)) {
3566
                if (!isset($row['image'])) {
3567
                    $row['image'] = '';
3568
                }
3569
                $row['on_sale'] = '';
3570
                if ($checker) {
3571
                    $row['on_sale'] = $plugin->getItemByProduct(
3572
                        $row['id'],
3573
                        BuyCoursesPlugin::PRODUCT_TYPE_SESSION
3574
                    );
3575
                }
3576
                $sessions[] = $row;
3577
            }
3578
3579
            return $sessions;
3580
        }
3581
3582
        return false;
3583
    }
3584
3585
    /**
3586
     * Get all session categories (filter by access_url_id).
3587
     *
3588
     * @return mixed false if the session category does not exist, array if the session category exists
3589
     */
3590
    public static function get_all_session_category()
3591
    {
3592
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3593
        $id = api_get_current_access_url_id();
3594
        $sql = 'SELECT * FROM '.$table.'
3595
                WHERE access_url_id = '.$id.'
3596
                ORDER BY title ASC';
3597
        $result = Database::query($sql);
3598
        if (Database::num_rows($result) > 0) {
3599
            $data = Database::store_result($result, 'ASSOC');
3600
3601
            return $data;
3602
        }
3603
3604
        return false;
3605
    }
3606
3607
    /**
3608
     * Assign a coach to course in session with status = 2.
3609
     *
3610
     * @param int  $userId
3611
     * @param int  $sessionId
3612
     * @param int  $courseId
3613
     * @param bool $noCoach   optional, if is true the user don't be a coach now,
3614
     *                        otherwise it'll assign a coach
3615
     *
3616
     * @return bool true if there are affected rows, otherwise false
3617
     */
3618
    public static function set_coach_to_course_session(
3619
        $userId,
3620
        $sessionId = 0,
3621
        $courseId = 0,
3622
        $noCoach = false
3623
    ) {
3624
        $userId = (int) $userId;
3625
3626
        $sessionId = !empty($sessionId) ? (int) $sessionId : api_get_session_id();
3627
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_id();
3628
3629
        if (empty($sessionId) || empty($courseId) || empty($userId)) {
3630
            return false;
3631
        }
3632
3633
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3634
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3635
3636
        $user = api_get_user_entity($userId);
3637
3638
        if (!$user->hasRole('ROLE_TEACHER')) {
3639
            return false;
3640
        }
3641
3642
        if ($noCoach) {
3643
            // Delete the course-specific coach record
3644
            $sql = "DELETE FROM $tblSessionRelCourseRelUser
3645
                WHERE
3646
                    session_id = $sessionId AND
3647
                    c_id = $courseId AND
3648
                    user_id = $userId AND
3649
                    status = ".Session::COURSE_COACH;
3650
            $result = Database::query($sql);
3651
3652
            // Check if the user is still a coach for any course in this session
3653
            $sql = "SELECT COUNT(*) AS count FROM $tblSessionRelCourseRelUser
3654
                WHERE
3655
                    session_id = $sessionId AND
3656
                    user_id = $userId AND
3657
                    status = ".Session::COURSE_COACH;
3658
            $res = Database::query($sql);
3659
            $resultRow = Database::fetch_assoc($res);
3660
3661
            // If the user is no longer a coach for any course in this session, remove the session relationship
3662
            if (0 === (int) $resultRow['count']) {
3663
                $sql = "DELETE FROM $tblSessionRelUser
3664
                    WHERE
3665
                        session_id = $sessionId AND
3666
                        user_id = $userId AND
3667
                        relation_type = ".Session::COURSE_COACH;
3668
                Database::query($sql);
3669
            }
3670
3671
            return Database::affected_rows($result) > 0;
3672
        }
3673
3674
        // Assign user as a coach to course
3675
        // First check if the user is registered to the course
3676
        $sql = "SELECT user_id FROM $tblSessionRelCourseRelUser
3677
                WHERE
3678
                    session_id = $sessionId AND
3679
                    c_id = $courseId AND
3680
                    user_id = $userId";
3681
        $rs_check = Database::query($sql);
3682
3683
        // Then update or insert.
3684
        if (Database::num_rows($rs_check) > 0) {
3685
            $sql = "UPDATE $tblSessionRelCourseRelUser
3686
                    SET status = ".Session::COURSE_COACH."
3687
                    WHERE
3688
                        session_id = $sessionId AND
3689
                        c_id = $courseId AND
3690
                        user_id = $userId ";
3691
            $result = Database::query($sql);
3692
3693
            return Database::affected_rows($result) > 0;
3694
        }
3695
3696
        $sessionRepo = Container::getSessionRepository();
3697
3698
        $session = api_get_session_entity($sessionId);
3699
3700
        $sessionRepo->addUserInCourse(
3701
            Session::COURSE_COACH,
3702
            api_get_user_entity($userId),
3703
            api_get_course_entity($courseId),
3704
            $session
3705
        );
3706
3707
        $sessionRepo->update($session);
3708
3709
        return true;
3710
    }
3711
3712
    /**
3713
     * Subscribes sessions to human resource manager (Dashboard feature).
3714
     *
3715
     * @param array $userInfo               Human Resource Manager info
3716
     * @param array $sessions_list          Sessions id
3717
     * @param bool  $sendEmail
3718
     * @param bool  $removeSessionsFromUser
3719
     *
3720
     * @return int
3721
     * */
3722
    public static function subscribeSessionsToDrh(
3723
        $userInfo,
3724
        $sessions_list,
3725
        $sendEmail = false,
3726
        $removeSessionsFromUser = true
3727
    ) {
3728
        // Database Table Definitions
3729
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3730
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3731
3732
        if (empty($userInfo)) {
3733
            return 0;
3734
        }
3735
3736
        $userId = $userInfo['user_id'];
3737
3738
        // Only subscribe DRH users.
3739
        $rolesAllowed = [
3740
            DRH,
3741
            SESSIONADMIN,
3742
            PLATFORM_ADMIN,
3743
            COURSE_TUTOR,
3744
        ];
3745
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3746
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3747
            return 0;
3748
        }
3749
3750
        $affected_rows = 0;
3751
        // Deleting assigned sessions to hrm_id.
3752
        if ($removeSessionsFromUser) {
3753
            if (api_is_multiple_url_enabled()) {
3754
                $sql = "SELECT s.session_id
3755
                        FROM $tbl_session_rel_user s
3756
                        INNER JOIN $tbl_session_rel_access_url a
3757
                        ON (a.session_id = s.session_id)
3758
                        WHERE
3759
                            s.user_id = $userId AND
3760
                            relation_type = ".Session::DRH." AND
3761
                            access_url_id = ".api_get_current_access_url_id();
3762
            } else {
3763
                $sql = "SELECT s.session_id
3764
                        FROM $tbl_session_rel_user s
3765
                        WHERE user_id = $userId AND relation_type=".Session::DRH;
3766
            }
3767
            $result = Database::query($sql);
3768
3769
            if (Database::num_rows($result) > 0) {
3770
                while ($row = Database::fetch_array($result)) {
3771
                    $sql = "DELETE FROM $tbl_session_rel_user
3772
                            WHERE
3773
                                session_id = {$row['session_id']} AND
3774
                                user_id = $userId AND
3775
                                relation_type =".Session::DRH;
3776
                    Database::query($sql);
3777
                }
3778
            }
3779
        }
3780
3781
        // Inserting new sessions list.
3782
        if (!empty($sessions_list) && is_array($sessions_list)) {
3783
            foreach ($sessions_list as $session_id) {
3784
                $session_id = intval($session_id);
3785
                $sql = "SELECT session_id
3786
                        FROM $tbl_session_rel_user
3787
                        WHERE
3788
                            session_id = $session_id AND
3789
                            user_id = $userId AND
3790
                            relation_type = '".Session::DRH."'";
3791
                $result = Database::query($sql);
3792
                if (0 == Database::num_rows($result)) {
3793
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3794
                            VALUES (
3795
                                $session_id,
3796
                                $userId,
3797
                                '".Session::DRH."',
3798
                                '".api_get_utc_datetime()."'
3799
                            )";
3800
                    Database::query($sql);
3801
                    $affected_rows++;
3802
                }
3803
            }
3804
        }
3805
3806
        return $affected_rows;
3807
    }
3808
3809
    /**
3810
     * @param int $sessionId
3811
     *
3812
     * @return array
3813
     */
3814
    public static function getDrhUsersInSession($sessionId)
3815
    {
3816
        return self::get_users_by_session($sessionId, Session::DRH);
3817
    }
3818
3819
    /**
3820
     * @param int $userId
3821
     * @param int $sessionId
3822
     *
3823
     * @return array
3824
     */
3825
    public static function getSessionFollowedByDrh($userId, $sessionId)
3826
    {
3827
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3828
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3829
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3830
3831
        $userId = (int) $userId;
3832
        $sessionId = (int) $sessionId;
3833
3834
        $select = " SELECT * ";
3835
        if (api_is_multiple_url_enabled()) {
3836
            $sql = " $select FROM $tbl_session s
3837
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3838
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3839
                    WHERE
3840
                        sru.user_id = '$userId' AND
3841
                        sru.session_id = '$sessionId' AND
3842
                        sru.relation_type = '".Session::DRH."' AND
3843
                        access_url_id = ".api_get_current_access_url_id()."
3844
                    ";
3845
        } else {
3846
            $sql = "$select FROM $tbl_session s
3847
                     INNER JOIN $tbl_session_rel_user sru
3848
                     ON
3849
                        sru.session_id = s.id AND
3850
                        sru.user_id = '$userId' AND
3851
                        sru.session_id = '$sessionId' AND
3852
                        sru.relation_type = '".Session::DRH."'
3853
                    ";
3854
        }
3855
3856
        $result = Database::query($sql);
3857
        if (Database::num_rows($result)) {
3858
            $row = Database::fetch_assoc($result);
3859
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3860
3861
            return $row;
3862
        }
3863
3864
        return [];
3865
    }
3866
3867
    /**
3868
     * Get sessions followed by human resources manager.
3869
     *
3870
     * @param int    $userId
3871
     * @param int    $start
3872
     * @param int    $limit
3873
     * @param bool   $getCount
3874
     * @param bool   $getOnlySessionId
3875
     * @param bool   $getSql
3876
     * @param string $orderCondition
3877
     * @param string $keyword
3878
     * @param string $description
3879
     * @param array  $options
3880
     *
3881
     * @return array sessions
3882
     */
3883
    public static function get_sessions_followed_by_drh(
3884
        $userId,
3885
        $start = null,
3886
        $limit = null,
3887
        $getCount = false,
3888
        $getOnlySessionId = false,
3889
        $getSql = false,
3890
        $orderCondition = null,
3891
        $keyword = '',
3892
        $description = '',
3893
        $options = []
3894
    ) {
3895
        return self::getSessionsFollowedByUser(
3896
            $userId,
3897
            DRH,
3898
            $start,
3899
            $limit,
3900
            $getCount,
3901
            $getOnlySessionId,
3902
            $getSql,
3903
            $orderCondition,
3904
            $keyword,
3905
            $description,
3906
            $options
3907
        );
3908
    }
3909
3910
    /**
3911
     * Get sessions followed by human resources manager.
3912
     *
3913
     * @param int    $userId
3914
     * @param int    $status           DRH Optional
3915
     * @param int    $start
3916
     * @param int    $limit
3917
     * @param bool   $getCount
3918
     * @param bool   $getOnlySessionId
3919
     * @param bool   $getSql
3920
     * @param string $orderCondition
3921
     * @param string $keyword
3922
     * @param string $description
3923
     * @param array  $options
3924
     *
3925
     * @return array|string sessions
3926
     */
3927
    public static function getSessionsFollowedByUser(
3928
        $userId,
3929
        $status = null,
3930
        $start = null,
3931
        $limit = null,
3932
        $getCount = false,
3933
        $getOnlySessionId = false,
3934
        $getSql = false,
3935
        $orderCondition = null,
3936
        $keyword = '',
3937
        $description = '',
3938
        $options = []
3939
    ) {
3940
        // Database Table Definitions
3941
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3942
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3943
3944
        $extraFieldModel = new ExtraFieldModel('session');
3945
        $conditions = $extraFieldModel->parseConditions($options);
3946
        $sqlInjectJoins = $conditions['inject_joins'];
3947
        $extraFieldsConditions = $conditions['where'];
3948
        $sqlInjectWhere = $conditions['inject_where'];
3949
        $injectExtraFields = $conditions['inject_extra_fields'];
3950
3951
        if (!empty($injectExtraFields)) {
3952
            $injectExtraFields = ' , '.$injectExtraFields.' s.id';
3953
        }
3954
3955
        $userId = (int) $userId;
3956
        $user = api_get_user_entity($userId);
3957
3958
        $select = ' SELECT DISTINCT * '.$injectExtraFields;
3959
        if ($getCount) {
3960
            $select = ' SELECT count(DISTINCT(s.id)) as count ';
3961
        }
3962
3963
        if ($getOnlySessionId) {
3964
            $select = ' SELECT DISTINCT(s.id) ';
3965
        }
3966
3967
        $limitCondition = null;
3968
        if (!is_null($start) && !is_null($limit)) {
3969
            $limitCondition = " LIMIT ".intval($start).", ".intval($limit);
3970
        }
3971
3972
        if (empty($orderCondition)) {
3973
            $orderCondition = ' ORDER BY s.title ';
3974
        }
3975
3976
        $whereConditions = null;
3977
3978
        switch ($status) {
3979
            case DRH:
3980
                $sessionsQuery = array_map(
3981
                    fn(Session $session) => $session->getId(),
3982
                    $user->getDRHSessions()
3983
                );
3984
                break;
3985
            case COURSEMANAGER:
3986
                $coachSessions = array_map(
3987
                    fn(Session $session) => $session->getId(),
3988
                    $user->getSessionsByStatusInCourseSubscription(Session::COURSE_COACH)->getValues()
3989
                );
3990
                $generalCoachSessions = array_map(
3991
                    fn(Session $session) => $session->getId(),
3992
                    $user->getSessionsAsGeneralCoach()
3993
                );
3994
3995
                $sessionsQuery = array_merge($coachSessions, $generalCoachSessions);
3996
                break;
3997
            case SESSIONADMIN:
3998
                $sessionsQuery = array_map(
3999
                    fn(Session $session) => $session->getId(),
4000
                    $user->getSessionsAsAdmin()
4001
                );
4002
                break;
4003
            default:
4004
                $sessionsQuery = array_map(
4005
                    fn(Session $session) => $session->getId(),
4006
                    $user->getSessionsAsStudent()
4007
                );
4008
                break;
4009
        }
4010
4011
        $keywordCondition = '';
4012
        if (!empty($keyword)) {
4013
            $keyword = Database::escape_string($keyword);
4014
            $keywordCondition = " AND (s.title LIKE '%$keyword%' ) ";
4015
            if (!empty($description)) {
4016
                $description = Database::escape_string($description);
4017
                $keywordCondition = " AND (s.title LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
4018
            }
4019
        }
4020
4021
        $whereConditions .= $keywordCondition;
4022
        $subQuery = !empty($sessionsQuery) ? (' AND s.id IN ('.implode(',', $sessionsQuery).')') : '';
4023
4024
        $sql = " $select
4025
                FROM $tbl_session s
4026
                INNER JOIN $tbl_session_rel_access_url a
4027
                ON (s.id = a.session_id)
4028
                $sqlInjectJoins
4029
                WHERE
4030
                    access_url_id = ".api_get_current_access_url_id()."
4031
                    $subQuery
4032
                    $whereConditions
4033
                    $extraFieldsConditions
4034
                    $sqlInjectWhere
4035
                    $orderCondition
4036
                    $limitCondition";
4037
4038
        if ($getSql) {
4039
            return $sql;
4040
        }
4041
        $result = Database::query($sql);
4042
4043
        if ($getCount) {
4044
            $row = Database::fetch_array($result);
4045
            if ($row) {
4046
                return (int) $row['count'];
4047
            }
4048
4049
            return 0;
4050
        }
4051
4052
        $sessions = [];
4053
        if (Database::num_rows($result) > 0) {
4054
            $imgPath = Display::return_icon(
4055
                'session_default_small.png',
4056
                null,
4057
                [],
4058
                ICON_SIZE_SMALL,
4059
                false,
4060
                true
4061
            );
4062
4063
            $extraFieldValue = new ExtraFieldValue('session');
4064
            while ($row = Database::fetch_array($result)) {
4065
                if ($getOnlySessionId) {
4066
                    $sessions[$row['id']] = $row;
4067
                    continue;
4068
                }
4069
4070
                $extraFieldImage = $extraFieldValue->get_values_by_handler_and_field_variable($row['id'], 'image');
4071
                $image = $imgPath;
4072
                if (!empty($extraFieldImage) && isset($extraFieldImage['url'])) {
4073
                    $image = $extraFieldImage['url'];
4074
                }
4075
                $row['image'] = $image;
4076
                if ('0000-00-00 00:00:00' === $row['display_start_date'] || '0000-00-00' === $row['display_start_date']) {
4077
                    $row['display_start_date'] = null;
4078
                }
4079
4080
                if ('0000-00-00 00:00:00' === $row['display_end_date'] || '0000-00-00' === $row['display_end_date']) {
4081
                    $row['display_end_date'] = null;
4082
                }
4083
4084
                if ('0000-00-00 00:00:00' === $row['access_start_date'] || '0000-00-00' === $row['access_start_date']) {
4085
                    $row['access_start_date'] = null;
4086
                }
4087
4088
                if ('0000-00-00 00:00:00' === $row['access_end_date'] || '0000-00-00' === $row['access_end_date']) {
4089
                    $row['access_end_date'] = null;
4090
                }
4091
4092
                if ('0000-00-00 00:00:00' === $row['coach_access_start_date'] ||
4093
                    '0000-00-00' === $row['coach_access_start_date']
4094
                ) {
4095
                    $row['coach_access_start_date'] = null;
4096
                }
4097
4098
                if ('0000-00-00 00:00:00' === $row['coach_access_end_date'] ||
4099
                    '0000-00-00' === $row['coach_access_end_date']
4100
                ) {
4101
                    $row['coach_access_end_date'] = null;
4102
                }
4103
4104
                $sessions[$row['id']] = $row;
4105
            }
4106
        }
4107
4108
        return $sessions;
4109
    }
4110
4111
    /**
4112
     * Gets the list (or the count) of courses by session filtered by access_url.
4113
     *
4114
     * @param int    $session_id  The session id
4115
     * @param string $course_name The course code
4116
     * @param string $orderBy     Field to order the data
4117
     * @param bool   $getCount    Optional. Count the session courses
4118
     *
4119
     * @return array|int List of courses. Whether $getCount is true, return the count
4120
     */
4121
    public static function get_course_list_by_session_id(
4122
        $session_id,
4123
        $course_name = '',
4124
        $orderBy = null,
4125
        $getCount = false
4126
    ) {
4127
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4128
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4129
        $session_id = (int) $session_id;
4130
        $sqlSelect = '*, c.id, c.id as real_id, c.code as course_code';
4131
4132
        if ($getCount) {
4133
            $sqlSelect = 'COUNT(1) as count';
4134
        }
4135
4136
        // select the courses
4137
        $sql = "SELECT $sqlSelect
4138
                FROM $tbl_course c
4139
                INNER JOIN $tbl_session_rel_course src
4140
                ON (c.id = src.c_id)
4141
		        WHERE src.session_id = '$session_id' ";
4142
4143
        if (!empty($course_name)) {
4144
            $course_name = Database::escape_string($course_name);
4145
            $sql .= " AND c.title LIKE '%$course_name%' ";
4146
        }
4147
4148
        if (!empty($orderBy)) {
4149
            $orderBy = Database::escape_string($orderBy);
4150
            $orderBy = " ORDER BY $orderBy";
4151
        } else {
4152
            if (self::orderCourseIsEnabled()) {
4153
                $orderBy .= ' ORDER BY position ';
4154
            } else {
4155
                $orderBy .= ' ORDER BY title ';
4156
            }
4157
        }
4158
4159
        $sql .= Database::escape_string($orderBy);
4160
        $result = Database::query($sql);
4161
        $num_rows = Database::num_rows($result);
4162
        $courses = [];
4163
        if ($num_rows > 0) {
4164
            if ($getCount) {
4165
                $count = Database::fetch_assoc($result);
4166
4167
                return (int) $count['count'];
4168
            }
4169
4170
            while ($row = Database::fetch_assoc($result)) {
4171
                $courses[$row['real_id']] = $row;
4172
            }
4173
        }
4174
4175
        return $courses;
4176
    }
4177
4178
    /**
4179
     * Gets the list of courses by session filtered by access_url.
4180
     *
4181
     * @param $userId
4182
     * @param $sessionId
4183
     * @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...
4184
     * @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...
4185
     * @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...
4186
     * @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...
4187
     * @param bool   $getCount
4188
     * @param string $keyword
4189
     *
4190
     * @return array
4191
     */
4192
    public static function getAllCoursesFollowedByUser(
4193
        $userId,
4194
        $sessionId,
4195
        $from = null,
4196
        $limit = null,
4197
        $column = null,
4198
        $direction = null,
4199
        $getCount = false,
4200
        $keyword = ''
4201
    ) {
4202
        if (empty($sessionId)) {
4203
            $sessionsSQL = self::get_sessions_followed_by_drh(
4204
                $userId,
4205
                null,
4206
                null,
4207
                null,
4208
                true,
4209
                true
4210
            );
4211
        } else {
4212
            $sessionsSQL = intval($sessionId);
4213
        }
4214
4215
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4216
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4217
4218
        if ($getCount) {
4219
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
4220
        } else {
4221
            $select = "SELECT DISTINCT c.* ";
4222
        }
4223
4224
        $keywordCondition = null;
4225
        if (!empty($keyword)) {
4226
            $keyword = Database::escape_string($keyword);
4227
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4228
        }
4229
4230
        // Select the courses
4231
        $sql = "$select
4232
                FROM $tbl_course c
4233
                INNER JOIN $tbl_session_rel_course src
4234
                ON c.id = src.c_id
4235
		        WHERE
4236
		            src.session_id IN ($sessionsSQL)
4237
		            $keywordCondition
4238
		        ";
4239
        if ($getCount) {
4240
            $result = Database::query($sql);
4241
            $row = Database::fetch_assoc($result);
4242
4243
            return $row['count'];
4244
        }
4245
4246
        if (isset($from) && isset($limit)) {
4247
            $from = intval($from);
4248
            $limit = intval($limit);
4249
            $sql .= " LIMIT $from, $limit";
4250
        }
4251
4252
        $result = Database::query($sql);
4253
        $num_rows = Database::num_rows($result);
4254
        $courses = [];
4255
4256
        if ($num_rows > 0) {
4257
            while ($row = Database::fetch_assoc($result)) {
4258
                $courses[$row['id']] = $row;
4259
            }
4260
        }
4261
4262
        return $courses;
4263
    }
4264
4265
    /**
4266
     * Gets the list of courses by session filtered by access_url.
4267
     *
4268
     * @param int    $session_id
4269
     * @param string $course_name
4270
     *
4271
     * @return array list of courses
4272
     */
4273
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
4274
    {
4275
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4276
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4277
4278
        $session_id = (int) $session_id;
4279
        $course_name = Database::escape_string($course_name);
4280
4281
        // select the courses
4282
        $sql = "SELECT c.id, c.title FROM $tbl_course c
4283
                INNER JOIN $tbl_session_rel_course src
4284
                ON c.id = src.c_id
4285
		        WHERE ";
4286
4287
        if (!empty($session_id)) {
4288
            $sql .= "src.session_id LIKE '$session_id' AND ";
4289
        }
4290
4291
        if (!empty($course_name)) {
4292
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
4293
        }
4294
4295
        $sql .= "ORDER BY title;";
4296
        $result = Database::query($sql);
4297
        $num_rows = Database::num_rows($result);
4298
        $courses = [];
4299
        if ($num_rows > 0) {
4300
            while ($row = Database::fetch_assoc($result)) {
4301
                $courses[$row['id']] = $row;
4302
            }
4303
        }
4304
4305
        return $courses;
4306
    }
4307
4308
    /**
4309
     * Gets the count of courses by session filtered by access_url.
4310
     *
4311
     * @param int session id
4312
     * @param string $keyword
4313
     *
4314
     * @return array list of courses
4315
     */
4316
    public static function getCourseCountBySessionId($session_id, $keyword = '')
4317
    {
4318
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4319
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4320
        $session_id = (int) $session_id;
4321
4322
        // select the courses
4323
        $sql = "SELECT COUNT(c.code) count
4324
                FROM $tbl_course c
4325
                INNER JOIN $tbl_session_rel_course src
4326
                ON c.id = src.c_id
4327
		        WHERE src.session_id = '$session_id' ";
4328
4329
        $keywordCondition = null;
4330
        if (!empty($keyword)) {
4331
            $keyword = Database::escape_string($keyword);
4332
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4333
        }
4334
        $sql .= $keywordCondition;
4335
4336
        $result = Database::query($sql);
4337
        $num_rows = Database::num_rows($result);
4338
        if ($num_rows > 0) {
4339
            $row = Database::fetch_assoc($result);
4340
4341
            return $row['count'];
4342
        }
4343
4344
        return null;
4345
    }
4346
4347
    /**
4348
     * Get the session id based on the original id and field name in the extra fields.
4349
     * Returns 0 if session was not found.
4350
     *
4351
     * @param string $value    Original session id
4352
     * @param string $variable Original field name
4353
     *
4354
     * @return int Session id
4355
     */
4356
    public static function getSessionIdFromOriginalId($value, $variable)
4357
    {
4358
        $extraFieldValue = new ExtraFieldValue('session');
4359
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
4360
            $variable,
4361
            $value
4362
        );
4363
4364
        if (!empty($result)) {
4365
            return $result['item_id'];
4366
        }
4367
4368
        return 0;
4369
    }
4370
4371
    /**
4372
     * Get users by session.
4373
     *
4374
     * @param int  $id       session id
4375
     * @param int  $status   filter by status coach = 2
4376
     * @param bool $getCount Optional. Allow get the number of rows from the result
4377
     * @param int  $urlId
4378
     *
4379
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
4380
     */
4381
    public static function get_users_by_session(
4382
        $id,
4383
        $status = null,
4384
        $getCount = false,
4385
        $urlId = 0
4386
    ) {
4387
        if (empty($id)) {
4388
            return [];
4389
        }
4390
        $id = (int) $id;
4391
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
4392
4393
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4394
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4395
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
4396
4397
        $selectedField = '
4398
            u.id as user_id, u.lastname, u.firstname, u.username, su.relation_type, au.access_url_id,
4399
            su.moved_to, su.moved_status, su.moved_at, su.registered_at
4400
        ';
4401
4402
        if ($getCount) {
4403
            $selectedField = 'count(1) AS count';
4404
        }
4405
4406
        $sql = "SELECT $selectedField
4407
                FROM $tbl_user u
4408
                INNER JOIN $tbl_session_rel_user su
4409
                ON u.id = su.user_id AND
4410
                su.session_id = $id
4411
                LEFT OUTER JOIN $table_access_url_user au
4412
                ON (au.user_id = u.id)
4413
                ";
4414
4415
        if (is_numeric($status)) {
4416
            $status = (int) $status;
4417
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
4418
        } else {
4419
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
4420
        }
4421
4422
        $sql .= ' AND u.active <> '.USER_SOFT_DELETED.' ORDER BY su.relation_type, ';
4423
        $sql .= api_sort_by_first_name() ? ' u.firstname, u.lastname' : '  u.lastname, u.firstname';
4424
4425
        $result = Database::query($sql);
4426
        if ($getCount) {
4427
            $count = Database::fetch_assoc($result);
4428
            if ($count) {
4429
                return (int) $count['count'];
4430
            }
4431
4432
            return 0;
4433
        }
4434
4435
        $return = [];
4436
        while ($row = Database::fetch_assoc($result)) {
4437
            $return[] = $row;
4438
        }
4439
4440
        return $return;
4441
    }
4442
4443
    /**
4444
     * The general coach (session_rel_user.relation_type = Session::GENERAL_COACH).
4445
     *
4446
     * @param int  $user_id         user id
4447
     * @param bool $asPlatformAdmin The user is platform admin, return everything
4448
     *
4449
     * @return array
4450
     */
4451
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
4452
    {
4453
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
4454
        $user_id = (int) $user_id;
4455
4456
        $innerJoin = '';
4457
        $whereConditions = '';
4458
4459
        if (!$asPlatformAdmin) {
4460
            $innerJoin = " INNER JOIN session_rel_user AS sru ON (s.id = sru.session_id) ";
4461
            $whereConditions = "sru.user_id = $user_id AND sru.relation_type = ".Session::GENERAL_COACH;
4462
        }
4463
4464
        if (api_is_multiple_url_enabled()) {
4465
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4466
            $access_url_id = api_get_current_access_url_id();
4467
4468
            if (-1 != $access_url_id) {
4469
                $innerJoin .= " INNER JOIN $tblSessionRelAccessUrl session_rel_url
4470
                    ON (s.id = access_url_rel_session.session_id)";
4471
                $whereConditions .= " AND access_url_rel_session.access_url_id = $access_url_id";
4472
            }
4473
        }
4474
        $sql = "SELECT s.* FROM $sessionTable AS s $innerJoin ";
4475
        if (!empty($whereConditions)) {
4476
            $sql .= "WHERE $whereConditions ";
4477
        }
4478
        $sql .= "ORDER BY s.title";
4479
        $result = Database::query($sql);
4480
4481
        return Database::store_result($result, 'ASSOC');
4482
    }
4483
4484
    /**
4485
     * @param int $user_id
4486
     * @param int $courseId
4487
     * @param int $session_id
4488
     *
4489
     * @return array|bool
4490
     */
4491
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
4492
    {
4493
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4494
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4495
        $sql = "SELECT session_rcru.status
4496
                FROM $table session_rcru
4497
                INNER JOIN $tbl_user user
4498
                ON (session_rcru.user_id = user.id)
4499
                WHERE
4500
                    session_rcru.session_id = '".intval($session_id)."' AND
4501
                    session_rcru.c_id ='".intval($courseId)."' AND
4502
                    user.id = ".intval($user_id);
4503
4504
        $result = Database::query($sql);
4505
        $status = false;
4506
        if (Database::num_rows($result)) {
4507
            $status = Database::fetch_row($result);
4508
            $status = $status['0'];
4509
        }
4510
4511
        return $status;
4512
    }
4513
4514
    /**
4515
     * Gets user status within a session.
4516
     *
4517
     * @param int $userId
4518
     * @param int $sessionId
4519
     *
4520
     * @return SessionRelUser
4521
     */
4522
    public static function getUserStatusInSession($userId, $sessionId)
4523
    {
4524
        $em = Database::getManager();
4525
        $subscriptions = $em
4526
            ->getRepository(SessionRelUser::class)
4527
            ->findBy(['session' => $sessionId, 'user' => $userId]);
4528
4529
        /** @var SessionRelUser $subscription */
4530
        $subscription = current($subscriptions);
4531
4532
        return $subscription;
4533
    }
4534
4535
    /**
4536
     * @param int $id
4537
     *
4538
     * @return array
4539
     */
4540
    public static function get_all_sessions_by_promotion($id)
4541
    {
4542
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4543
4544
        return Database::select(
4545
            '*',
4546
            $table,
4547
            ['where' => ['promotion_id = ?' => $id]]
4548
        );
4549
    }
4550
4551
    /**
4552
     * @param int   $promotion_id
4553
     * @param array $list
4554
     */
4555
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
4556
    {
4557
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4558
        $params = [];
4559
        $params['promotion_id'] = 0;
4560
        Database::update(
4561
            $table,
4562
            $params,
4563
            ['promotion_id = ?' => $promotion_id]
4564
        );
4565
4566
        $params['promotion_id'] = $promotion_id;
4567
        if (!empty($list)) {
4568
            foreach ($list as $session_id) {
4569
                $session_id = (int) $session_id;
4570
                Database::update($table, $params, ['id = ?' => $session_id]);
4571
            }
4572
        }
4573
    }
4574
4575
    /**
4576
     * Updates a session status.
4577
     *
4578
     * @param int session id
4579
     * @param int status
4580
     */
4581
    public static function set_session_status($session_id, $status)
4582
    {
4583
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
4584
        $params['visibility'] = $status;
4585
        Database::update($t, $params, ['id = ?' => $session_id]);
4586
    }
4587
4588
    /**
4589
     * Copies a session with the same data to a new session.
4590
     * The new copy is not assigned to the same promotion.
4591
     *
4592
     * @param int  $id                         Session ID
4593
     * @param bool $copy_courses               Whether to copy the relationship with courses
4594
     * @param bool $copyTeachersAndDrh
4595
     * @param bool $create_new_courses         New courses will be created
4596
     * @param bool $set_exercises_lp_invisible Set exercises and LPs in the new session to invisible by default
4597
     *
4598
     * @return int The new session ID on success, 0 otherwise
4599
     *
4600
     * @see subscribe_sessions_to_promotions() for that.
4601
     *
4602
     * @todo make sure the extra session fields are copied too
4603
     */
4604
    public static function copy(
4605
        $id,
4606
        $copy_courses = true,
4607
        $copyTeachersAndDrh = true,
4608
        $create_new_courses = false,
4609
        $set_exercises_lp_invisible = false
4610
    ) {
4611
        $id = (int) $id;
4612
        $s = self::fetch($id);
4613
4614
        if (empty($s)) {
4615
            return false;
4616
        }
4617
4618
        // Check all dates before copying
4619
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
4620
        $now = time() - date('Z');
4621
        // Timestamp in one month
4622
        $inOneMonth = $now + (30 * 24 * 3600);
4623
        $inOneMonth = api_get_local_time($inOneMonth);
4624
        if (api_strtotime($s['access_start_date']) < $now) {
4625
            $s['access_start_date'] = api_get_local_time($now);
4626
        } else {
4627
            $s['access_start_date'] = api_get_local_time($s['access_start_date']);
4628
        }
4629
        if (api_strtotime($s['display_start_date']) < $now) {
4630
            $s['display_start_date'] = api_get_local_time($now);
4631
        } else {
4632
            $s['display_start_date'] = api_get_local_time($s['display_start_date']);
4633
        }
4634
        if (api_strtotime($s['coach_access_start_date']) < $now) {
4635
            $s['coach_access_start_date'] = api_get_local_time($now);
4636
        } else {
4637
            $s['coach_access_start_date'] = api_get_local_time($s['coach_access_start_date']);
4638
        }
4639
        if (api_strtotime($s['access_end_date']) < $now) {
4640
            $s['access_end_date'] = $inOneMonth;
4641
        } else {
4642
            $s['access_end_date'] = api_get_local_time($s['access_end_date']);
4643
        }
4644
        if (api_strtotime($s['display_end_date']) < $now) {
4645
            $s['display_end_date'] = $inOneMonth;
4646
        } else {
4647
            $s['display_end_date'] = api_get_local_time($s['display_end_date']);
4648
        }
4649
        if (api_strtotime($s['coach_access_end_date']) < $now) {
4650
            $s['coach_access_end_date'] = $inOneMonth;
4651
        } else {
4652
            $s['coach_access_end_date'] = api_get_local_time($s['coach_access_end_date']);
4653
        }
4654
4655
        $extraFieldValue = new ExtraFieldValue('session');
4656
        $extraFieldsValues = $extraFieldValue->getAllValuesByItem($id);
4657
        $extraFieldsValuesToCopy = [];
4658
        if (!empty($extraFieldsValues)) {
4659
            foreach ($extraFieldsValues as $extraFieldValue) {
4660
                //$extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4661
                $extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']]['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4662
            }
4663
        }
4664
4665
        // @todo fix session image url copy.
4666
        /*if (isset($extraFieldsValuesToCopy['extra_image']) &&
4667
            isset($extraFieldsValuesToCopy['extra_image']['extra_image'])
4668
        ) {
4669
            $extraFieldsValuesToCopy['extra_image'] = [
4670
                'tmp_name' => api_get_path(SYS_UPLOAD_PATH).$extraFieldsValuesToCopy['extra_image']['extra_image'],
4671
                'error' => 0,
4672
            ];
4673
        }*/
4674
4675
        $generalCoaches = self::getGeneralCoachesIdForSession($id);
4676
4677
        // Now try to create the session
4678
        $sid = self::create_session(
4679
            $s['title'].' '.get_lang('Copy'),
4680
            $s['access_start_date'],
4681
            $s['access_end_date'],
4682
            $s['display_start_date'],
4683
            $s['display_end_date'],
4684
            $s['coach_access_start_date'],
4685
            $s['coach_access_end_date'],
4686
            $generalCoaches,
4687
            $s['session_category_id'],
4688
            (int) $s['visibility'],
4689
            true,
4690
            $s['duration'],
4691
            $s['description'],
4692
            $s['show_description'],
4693
            $extraFieldsValuesToCopy
4694
        );
4695
4696
        if (!is_numeric($sid) || empty($sid)) {
4697
            return false;
4698
        }
4699
4700
        if ($copy_courses) {
4701
            // Register courses from the original session to the new session
4702
            $courses = self::get_course_list_by_session_id($id);
4703
            $short_courses = $new_short_courses = [];
4704
            if (is_array($courses) && count($courses) > 0) {
4705
                foreach ($courses as $course) {
4706
                    $short_courses[] = $course;
4707
                }
4708
            }
4709
4710
            // We will copy the current courses of the session to new courses
4711
            if (!empty($short_courses)) {
4712
                if ($create_new_courses) {
4713
                    api_set_more_memory_and_time_limits();
4714
                    $params = [];
4715
                    $params['skip_lp_dates'] = true;
4716
4717
                    foreach ($short_courses as $course_data) {
4718
                        $course = CourseManager::copy_course_simple(
4719
                            $course_data['title'].' '.get_lang(
4720
                                'Copy'
4721
                            ),
4722
                            $course_data['course_code'],
4723
                            $id,
4724
                            $sid,
4725
                            $params
4726
                        );
4727
4728
                        if (null !== $course) {
4729
                            $course_info = api_get_course_info($course->getCode());
4730
                            //By default new elements are invisible
4731
                            if ($set_exercises_lp_invisible) {
4732
                                $list = new LearnpathList('', $course_info, $sid);
4733
                                $flat_list = $list->get_flat_list();
4734
                                if (!empty($flat_list)) {
4735
                                    foreach ($flat_list as $lp_id => $data) {
4736
                                        // @todo fix
4737
                                        /*api_item_property_update(
4738
                                            $course_info,
4739
                                            TOOL_LEARNPATH,
4740
                                            $lp_id,
4741
                                            'invisible',
4742
                                            api_get_user_id(),
4743
                                            0,
4744
                                            0,
4745
                                            0,
4746
                                            0,
4747
                                            $sid
4748
                                        );*/
4749
                                    }
4750
                                }
4751
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4752
                                $course_id = $course_info['real_id'];
4753
                                //@todo check this query
4754
                                $sql = "UPDATE $quiz_table SET active = 0
4755
                                        WHERE c_id = $course_id AND session_id = $sid";
4756
                                Database::query($sql);
4757
                            }
4758
                            $new_short_courses[] = $course_info['real_id'];
4759
                        }
4760
                    }
4761
                } else {
4762
                    foreach ($short_courses as $course_data) {
4763
                        $new_short_courses[] = $course_data['id'];
4764
                    }
4765
                }
4766
4767
                $short_courses = $new_short_courses;
4768
                self::add_courses_to_session($sid, $short_courses, true);
4769
4770
                if (false === $create_new_courses && $copyTeachersAndDrh) {
4771
                    foreach ($short_courses as $courseItemId) {
4772
                        $coachList = self::getCoachesByCourseSession($id, $courseItemId);
4773
                        foreach ($coachList as $userId) {
4774
                            self::set_coach_to_course_session($userId, $sid, $courseItemId);
4775
                        }
4776
                    }
4777
                }
4778
            }
4779
        }
4780
4781
        if ($copyTeachersAndDrh) {
4782
            // Register users from the original session to the new session
4783
            $users = self::get_users_by_session($id);
4784
            if (!empty($users)) {
4785
                $userListByStatus = [];
4786
                foreach ($users as $userData) {
4787
                    $userData['relation_type'] = (int) $userData['relation_type'];
4788
                    $userListByStatus[$userData['relation_type']][] = $userData;
4789
                }
4790
4791
                foreach ($userListByStatus as $status => $userList) {
4792
                    $userList = array_column($userList, 'user_id');
4793
                    switch ($status) {
4794
                        case 0:
4795
                            /*self::subscribeUsersToSession(
4796
                                $sid,
4797
                                $userList,
4798
                                SESSION_VISIBLE_READ_ONLY,
4799
                                false,
4800
                                true
4801
                            );*/
4802
                            break;
4803
                        case 1:
4804
                            // drh users
4805
                            foreach ($userList as $drhId) {
4806
                                $userInfo = api_get_user_info($drhId);
4807
                                self::subscribeSessionsToDrh($userInfo, [$sid], false, false);
4808
                            }
4809
                            break;
4810
                    }
4811
                }
4812
            }
4813
        }
4814
4815
        return $sid;
4816
    }
4817
4818
    /**
4819
     * Get the number of sessions.
4820
     *
4821
     * @param int $access_url_id ID of the URL we want to filter on (optional)
4822
     *
4823
     * @return int Number of sessions
4824
     */
4825
    public static function count_sessions($access_url_id = 0)
4826
    {
4827
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4828
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4829
        $access_url_id = (int) $access_url_id;
4830
        $sql = "SELECT count(s.id) FROM $session_table s";
4831
        if (!empty($access_url_id)) {
4832
            $sql .= ", $access_url_rel_session_table u ".
4833
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4834
        }
4835
        $res = Database::query($sql);
4836
        $row = Database::fetch_row($res);
4837
4838
        return $row[0];
4839
    }
4840
4841
    public static function cantEditSession(?Session $session = null, bool $checkSession = true): bool
4842
    {
4843
        if (!self::allowToManageSessions()) {
4844
            return false;
4845
        }
4846
4847
        if (api_is_platform_admin() && self::allowed($session)) {
4848
            return true;
4849
        }
4850
4851
        if ($checkSession) {
4852
            if (self::allowed($session)) {
4853
                return true;
4854
            }
4855
4856
            return false;
4857
        }
4858
4859
        return true;
4860
    }
4861
4862
    /**
4863
     * Protect a session to be edited.
4864
     *
4865
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4866
     */
4867
    public static function protectSession(?Session $session = null, bool $checkSession = true)
4868
    {
4869
        if (!self::cantEditSession($session, $checkSession)) {
4870
            api_not_allowed(true);
4871
        }
4872
    }
4873
4874
    public static function allowToManageSessions(): bool
4875
    {
4876
        if (self::allowManageAllSessions()) {
4877
            return true;
4878
        }
4879
4880
        if (api_is_teacher() && 'true' === api_get_setting('allow_teachers_to_create_sessions')) {
4881
            return true;
4882
        }
4883
4884
        return false;
4885
    }
4886
4887
    /**
4888
     * @return bool
4889
     */
4890
    public static function allowOnlyMySessions()
4891
    {
4892
        if (self::allowToManageSessions() &&
4893
            !api_is_platform_admin() &&
4894
            api_is_teacher()
4895
        ) {
4896
            return true;
4897
        }
4898
4899
        return false;
4900
    }
4901
4902
    /**
4903
     * @return bool
4904
     */
4905
    public static function allowManageAllSessions()
4906
    {
4907
        if (api_is_platform_admin() || api_is_session_admin()) {
4908
            return true;
4909
        }
4910
4911
        return false;
4912
    }
4913
4914
    /**
4915
     * @param $id
4916
     *
4917
     * @return bool
4918
     */
4919
    public static function protect_teacher_session_edit($id)
4920
    {
4921
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4922
            api_not_allowed(true);
4923
        } else {
4924
            return true;
4925
        }
4926
    }
4927
4928
    /**
4929
     * @param int $courseId
4930
     *
4931
     * @return array
4932
     */
4933
    public static function get_session_by_course($courseId)
4934
    {
4935
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4936
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4937
        $url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4938
        $courseId = (int) $courseId;
4939
        $urlId = api_get_current_access_url_id();
4940
4941
        if (empty($courseId)) {
4942
            return [];
4943
        }
4944
4945
        $sql = "SELECT title, s.id
4946
                FROM $table_session_course sc
4947
                INNER JOIN $table_session s
4948
                ON (sc.session_id = s.id)
4949
                INNER JOIN $url u
4950
                ON (u.session_id = s.id)
4951
                WHERE
4952
                    u.access_url_id = $urlId AND
4953
                    sc.c_id = '$courseId' ";
4954
        $result = Database::query($sql);
4955
4956
        return Database::store_result($result);
4957
    }
4958
4959
    /**
4960
     * @param int  $userId
4961
     * @param bool $ignoreVisibilityForAdmins
4962
     * @param bool $ignoreTimeLimit
4963
     *
4964
     * @return array
4965
     */
4966
    public static function get_sessions_by_user(
4967
        $userId,
4968
        $ignoreVisibilityForAdmins = false,
4969
        $ignoreTimeLimit = false
4970
    ) {
4971
        $sessionCategories = UserManager::get_sessions_by_category(
4972
            $userId,
4973
            false,
4974
            $ignoreVisibilityForAdmins,
4975
            $ignoreTimeLimit
4976
        );
4977
4978
        $sessionArray = [];
4979
        if (!empty($sessionCategories)) {
4980
            foreach ($sessionCategories as $category) {
4981
                if (isset($category['sessions'])) {
4982
                    foreach ($category['sessions'] as $session) {
4983
                        $sessionArray[] = $session;
4984
                    }
4985
                }
4986
            }
4987
        }
4988
4989
        return $sessionArray;
4990
    }
4991
4992
    /**
4993
     * @param string $file
4994
     * @param bool   $updateSession                                   true: if the session exists it will be updated.
4995
     *                                                                false: if session exists a new session will be created adding a counter session1, session2, etc
4996
     * @param int    $defaultUserId
4997
     * @param Logger $logger
4998
     * @param array  $extraFields                                     convert a file row to an extra field. Example in CSV file there's a SessionID
4999
     *                                                                then it will converted to extra_external_session_id if you set: array('SessionId' => 'extra_external_session_id')
5000
     * @param string $extraFieldId
5001
     * @param int    $daysCoachAccessBeforeBeginning
5002
     * @param int    $daysCoachAccessAfterBeginning
5003
     * @param int    $sessionVisibility
5004
     * @param array  $fieldsToAvoidUpdate
5005
     * @param bool   $deleteUsersNotInList
5006
     * @param bool   $updateCourseCoaches
5007
     * @param bool   $sessionWithCoursesModifier
5008
     * @param bool   $addOriginalCourseTeachersAsCourseSessionCoaches
5009
     * @param bool   $removeAllTeachersFromCourse
5010
     * @param int    $showDescription
5011
     * @param array  $teacherBackupList
5012
     * @param array  $groupBackup
5013
     *
5014
     * @return array
5015
     */
5016
    public static function importCSV(
5017
        $file,
5018
        $updateSession,
5019
        $defaultUserId = null,
5020
        $logger = null,
5021
        $extraFields = [],
5022
        $extraFieldId = null,
5023
        $daysCoachAccessBeforeBeginning = null,
5024
        $daysCoachAccessAfterBeginning = null,
5025
        $sessionVisibility = 1,
5026
        $fieldsToAvoidUpdate = [],
5027
        $deleteUsersNotInList = false,
5028
        $updateCourseCoaches = false,
5029
        $sessionWithCoursesModifier = false,
5030
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
5031
        $removeAllTeachersFromCourse = true,
5032
        $showDescription = null,
5033
        &$teacherBackupList = [],
5034
        &$groupBackup = []
5035
    ) {
5036
        $content = file($file);
5037
        $error_message = null;
5038
        $session_counter = 0;
5039
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
5040
5041
        $eol = PHP_EOL;
5042
        if (PHP_SAPI != 'cli') {
5043
            $eol = '<br />';
5044
        }
5045
5046
        $debug = false;
5047
        if (isset($logger)) {
5048
            $debug = true;
5049
        }
5050
5051
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5052
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
5053
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5054
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5055
        $sessions = [];
5056
        if (!api_strstr($content[0], ';')) {
5057
            $error_message = get_lang('The specified file is not CSV format !');
5058
        } else {
5059
            $tag_names = [];
5060
            foreach ($content as $key => $enreg) {
5061
                $enreg = explode(';', trim($enreg));
5062
                if ($key) {
5063
                    foreach ($tag_names as $tag_key => $tag_name) {
5064
                        if (isset($enreg[$tag_key])) {
5065
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
5066
                        }
5067
                    }
5068
                } else {
5069
                    foreach ($enreg as $tag_name) {
5070
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
5071
                    }
5072
                    if (!in_array('SessionName', $tag_names) ||
5073
                        !in_array('DateStart', $tag_names) ||
5074
                        !in_array('DateEnd', $tag_names)
5075
                    ) {
5076
                        $error_message = get_lang('The specified file doesn\'t contain all needed data !');
5077
                        break;
5078
                    }
5079
                }
5080
            }
5081
5082
            $sessionList = [];
5083
            $report = [];
5084
5085
            // Looping the sessions.
5086
            foreach ($sessions as $enreg) {
5087
                $user_counter = 0;
5088
                $course_counter = 0;
5089
5090
                if (isset($extraFields) && !empty($extraFields)) {
5091
                    foreach ($extraFields as $original => $to) {
5092
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
5093
                    }
5094
                }
5095
5096
                $session_name = $enreg['SessionName'];
5097
5098
                if ($debug) {
5099
                    $logger->debug('---------------------------------------');
5100
                    $logger->debug("Sessions - Start process of session: $session_name");
5101
                    $logger->debug('---------------------------------------');
5102
                }
5103
5104
                // Default visibility
5105
                $visibilityAfterExpirationPerSession = $sessionVisibility;
5106
5107
                if (isset($enreg['VisibilityAfterExpiration'])) {
5108
                    $visibility = $enreg['VisibilityAfterExpiration'];
5109
                    switch ($visibility) {
5110
                        case 'read_only':
5111
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
5112
                            break;
5113
                        case 'accessible':
5114
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
5115
                            break;
5116
                        case 'not_accessible':
5117
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
5118
                            break;
5119
                    }
5120
                }
5121
5122
                if (empty($session_name)) {
5123
                    continue;
5124
                }
5125
5126
                $displayAccessStartDate = isset($enreg['DisplayStartDate']) ? $enreg['DisplayStartDate'] : $enreg['DateStart'];
5127
                $displayAccessEndDate = isset($enreg['DisplayEndDate']) ? $enreg['DisplayEndDate'] : $enreg['DateEnd'];
5128
                $coachAccessStartDate = isset($enreg['CoachStartDate']) ? $enreg['CoachStartDate'] : $enreg['DateStart'];
5129
                $coachAccessEndDate = isset($enreg['CoachEndDate']) ? $enreg['CoachEndDate'] : $enreg['DateEnd'];
5130
                // We assume the dates are already in UTC
5131
                $dateStart = explode('/', $enreg['DateStart']);
5132
                $dateEnd = explode('/', $enreg['DateEnd']);
5133
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
5134
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
5135
                $displayAccessStartDate = explode('/', $displayAccessStartDate);
5136
                $displayAccessStartDate = implode('-', $displayAccessStartDate).' 00:00:00';
5137
                $displayAccessEndDate = explode('/', $displayAccessEndDate);
5138
                $displayAccessEndDate = implode('-', $displayAccessEndDate).' 23:59:59';
5139
                $coachAccessStartDate = explode('/', $coachAccessStartDate);
5140
                $coachAccessStartDate = implode('-', $coachAccessStartDate).' 00:00:00';
5141
                $coachAccessEndDate = explode('/', $coachAccessEndDate);
5142
                $coachAccessEndDate = implode('-', $coachAccessEndDate).' 23:59:59';
5143
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
5144
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
5145
                $classes = isset($enreg['Classes']) ? explode('|', $enreg['Classes']) : [];
5146
                $extraParams = [];
5147
                if (!is_null($showDescription)) {
5148
                    $extraParams['show_description'] = intval($showDescription);
5149
                }
5150
5151
                $coachBefore = '';
5152
                $coachAfter = '';
5153
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5154
                    $date = new \DateTime($dateStart);
5155
                    $interval = new DateInterval('P'.$daysCoachAccessBeforeBeginning.'D');
5156
                    $date->sub($interval);
5157
                    $coachBefore = $date->format('Y-m-d h:i');
5158
                    $coachAccessStartDate = $coachBefore;
5159
                    $coachBefore = api_get_utc_datetime($coachBefore);
5160
5161
                    $date = new \DateTime($dateEnd);
5162
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
5163
                    $date->add($interval);
5164
                    $coachAfter = $date->format('Y-m-d h:i');
5165
                    $coachAccessEndDate = $coachAfter;
5166
                    $coachAfter = api_get_utc_datetime($coachAfter);
5167
                }
5168
5169
                $dateStart = api_get_utc_datetime($dateStart);
5170
                $dateEnd = api_get_utc_datetime($dateEnd);
5171
                $displayAccessStartDate = api_get_utc_datetime($displayAccessStartDate);
5172
                $displayAccessEndDate = api_get_utc_datetime($displayAccessEndDate);
5173
                $coachAccessStartDate = api_get_utc_datetime($coachAccessStartDate);
5174
                $coachAccessEndDate = api_get_utc_datetime($coachAccessEndDate);
5175
5176
                if (!empty($sessionDescription)) {
5177
                    $extraParams['description'] = $sessionDescription;
5178
                }
5179
5180
                if (!empty($session_category_id)) {
5181
                    $extraParams['session_category_id'] = $session_category_id;
5182
                }
5183
5184
                // Searching a general coach.
5185
                if (!empty($enreg['Coach'])) {
5186
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
5187
                    if (false === $coach_id) {
5188
                        // If the coach-user does not exist - I'm the coach.
5189
                        $coach_id = $defaultUserId;
5190
                    }
5191
                } else {
5192
                    $coach_id = $defaultUserId;
5193
                }
5194
5195
                $users = explode('|', $enreg['Users']);
5196
                $courses = explode('|', $enreg['Courses']);
5197
5198
                $deleteOnlyCourseCoaches = false;
5199
                if (1 == count($courses)) {
5200
                    if ($logger) {
5201
                        $logger->debug('Only one course delete old coach list');
5202
                    }
5203
                    $deleteOnlyCourseCoaches = true;
5204
                }
5205
5206
                if (!$updateSession) {
5207
                    // Create a session.
5208
                    $unique_name = false;
5209
                    $i = 0;
5210
                    // Change session name, verify that session doesn't exist.
5211
                    $suffix = null;
5212
                    while (!$unique_name) {
5213
                        if ($i > 1) {
5214
                            $suffix = ' - '.$i;
5215
                        }
5216
                        $sql = 'SELECT id FROM '.$tbl_session.'
5217
                                WHERE title = "'.Database::escape_string($session_name).$suffix.'"';
5218
                        $rs = Database::query($sql);
5219
                        if (Database::result($rs, 0, 0)) {
5220
                            $i++;
5221
                        } else {
5222
                            $unique_name = true;
5223
                            $session_name .= $suffix;
5224
                        }
5225
                    }
5226
5227
                    $sessionParams = [
5228
                        'title' => $session_name,
5229
                        'access_start_date' => $dateStart,
5230
                        'access_end_date' => $dateEnd,
5231
                        'display_start_date' => $displayAccessStartDate,
5232
                        'display_end_date' => $displayAccessEndDate,
5233
                        'coach_access_start_date' => $coachAccessStartDate,
5234
                        'coach_access_end_date' => $coachAccessEndDate,
5235
                        'visibility' => $visibilityAfterExpirationPerSession,
5236
                        'nbr_users' => 0,
5237
                        'nbr_courses' => 0,
5238
                        'nbr_classes' => 0,
5239
                        'status' => 0,
5240
                        'duration' => 0,
5241
                    ];
5242
5243
                    if (!empty($extraParams)) {
5244
                        $sessionParams = array_merge($sessionParams, $extraParams);
5245
                    }
5246
                    // Creating the session.
5247
                    $session_id = Database::insert($tbl_session, $sessionParams);
5248
                    if ($session_id) {
5249
                        Database::insert(
5250
                            $tbl_session_user,
5251
                            [
5252
                                'relation_type' => Session::GENERAL_COACH,
5253
                                'duration' => 0,
5254
                                'registered_at' => api_get_utc_datetime(),
5255
                                'user_id' => $coach_id,
5256
                                'session_id' => $session_id,
5257
                            ]
5258
                        );
5259
                        Database::insert(
5260
                            $tbl_session_user,
5261
                            [
5262
                                'relation_type' => Session::GENERAL_COACH,
5263
                                'duration' => 0,
5264
                                'registered_at' => api_get_utc_datetime(),
5265
                                'user_id' => $defaultUserId,
5266
                                'session_id' => $session_id,
5267
                            ]
5268
                        );
5269
                        foreach ($enreg as $key => $value) {
5270
                            if ('extra_' === substr($key, 0, 6)) { //an extra field
5271
                                self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5272
                            }
5273
                        }
5274
                        if ($debug) {
5275
                            $logger->debug("Session created: #$session_id - $session_name");
5276
                        }
5277
                    } else {
5278
                        if ($debug) {
5279
                            $message = "Sessions - Session NOT created: $session_name";
5280
                            $logger->debug($message);
5281
                            $report[] = $message;
5282
                        }
5283
                    }
5284
                    $session_counter++;
5285
                } else {
5286
                    $sessionId = null;
5287
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
5288
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
5289
                        if (empty($sessionId)) {
5290
                            $my_session_result = false;
5291
                        } else {
5292
                            $my_session_result = true;
5293
                        }
5294
                    } else {
5295
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
5296
                    }
5297
5298
                    if (false === $my_session_result) {
5299
                        // One more check
5300
                        $sessionExistsWithName = self::get_session_by_name($session_name);
5301
                        if ($sessionExistsWithName) {
5302
                            if ($debug) {
5303
                                $message = "Skip Session - Trying to update a session, but name already exists: $session_name";
5304
                                $logger->debug($message);
5305
                                $report[] = $message;
5306
                            }
5307
                            continue;
5308
                        }
5309
5310
                        $sessionParams = [
5311
                            'title' => $session_name,
5312
                            'access_start_date' => $dateStart,
5313
                            'access_end_date' => $dateEnd,
5314
                            'display_start_date' => $displayAccessStartDate,
5315
                            'display_end_date' => $displayAccessEndDate,
5316
                            'coach_access_start_date' => $coachAccessStartDate,
5317
                            'coach_access_end_date' => $coachAccessEndDate,
5318
                            'visibility' => $visibilityAfterExpirationPerSession,
5319
                            'nbr_users' => 0,
5320
                            'nbr_courses' => 0,
5321
                            'nbr_classes' => 0,
5322
                            'status' => 0,
5323
                            'duration' => 0,
5324
                        ];
5325
5326
                        if (!empty($extraParams)) {
5327
                            $sessionParams = array_merge($sessionParams, $extraParams);
5328
                        }
5329
                        $session_id = Database::insert($tbl_session, $sessionParams);
5330
5331
                        if ($session_id) {
5332
                            Database::insert(
5333
                                $tbl_session_user,
5334
                                [
5335
                                    'relation_type' => Session::GENERAL_COACH,
5336
                                    'duration' => 0,
5337
                                    'registered_at' => api_get_utc_datetime(),
5338
                                    'user_id' => $coach_id,
5339
                                    'session_id' => $session_id,
5340
                                ]
5341
                            );
5342
                            Database::insert(
5343
                                $tbl_session_user,
5344
                                [
5345
                                    'relation_type' => Session::GENERAL_COACH,
5346
                                    'duration' => 0,
5347
                                    'registered_at' => api_get_utc_datetime(),
5348
                                    'user_id' => $defaultUserId,
5349
                                    'session_id' => $session_id,
5350
                                ]
5351
                            );
5352
                            foreach ($enreg as $key => $value) {
5353
                                if ('extra_' == substr($key, 0, 6)) { //an extra field
5354
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5355
                                }
5356
                            }
5357
                            if ($debug) {
5358
                                $logger->debug("Sessions - #$session_id created: $session_name");
5359
                            }
5360
5361
                            // Delete session-user relation only for students
5362
                            $sql = "DELETE FROM $tbl_session_user
5363
                                    WHERE session_id = '$session_id' AND relation_type = ".Session::STUDENT;
5364
                            Database::query($sql);
5365
5366
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5367
                            Database::query($sql);
5368
5369
                            // Delete session-course-user relationships students and coaches.
5370
                            if ($updateCourseCoaches) {
5371
                                $sql = "DELETE FROM $tbl_session_course_user
5372
                                        WHERE session_id = '$session_id' AND status in (".Session::STUDENT.", ".Session::COURSE_COACH.")";
5373
                                Database::query($sql);
5374
                            } else {
5375
                                // Delete session-course-user relation ships *only* for students.
5376
                                $sql = "DELETE FROM $tbl_session_course_user
5377
                                        WHERE session_id = '$session_id' AND status =".Session::STUDENT;
5378
                                Database::query($sql);
5379
                            }
5380
                            if ($deleteOnlyCourseCoaches) {
5381
                                $sql = "DELETE FROM $tbl_session_course_user
5382
                                        WHERE session_id = '$session_id' AND status = ".Session::COURSE_COACH;
5383
                                Database::query($sql);
5384
                            }
5385
                        }
5386
                    } else {
5387
                        // Updating the session.
5388
                        $params = [
5389
                            'access_start_date' => $dateStart,
5390
                            'access_end_date' => $dateEnd,
5391
                            'display_start_date' => $displayAccessStartDate,
5392
                            'display_end_date' => $displayAccessEndDate,
5393
                            'coach_access_start_date' => $coachAccessStartDate,
5394
                            'coach_access_end_date' => $coachAccessEndDate,
5395
                            'visibility' => $visibilityAfterExpirationPerSession,
5396
                            'session_category_id' => $session_category_id,
5397
                        ];
5398
5399
                        if (!empty($sessionDescription)) {
5400
                            $params['description'] = $sessionDescription;
5401
                        }
5402
5403
                        if (!empty($fieldsToAvoidUpdate)) {
5404
                            foreach ($fieldsToAvoidUpdate as $field) {
5405
                                unset($params[$field]);
5406
                            }
5407
                        }
5408
5409
                        if (isset($sessionId) && !empty($sessionId)) {
5410
                            $session_id = $sessionId;
5411
                            if (!empty($enreg['SessionName'])) {
5412
                                $sessionExistsWithName = self::get_session_by_name($session_name);
5413
                                if (false === $sessionExistsWithName) {
5414
                                    $sessionName = Database::escape_string($enreg['SessionName']);
5415
                                    $sql = "UPDATE $tbl_session SET title = '$sessionName' WHERE id = $session_id";
5416
                                    Database::query($sql);
5417
                                    $logger->debug(
5418
                                        "Session #$session_id name IS updated with: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
5419
                                    );
5420
                                } else {
5421
                                    $sessionExistsBesidesMe = self::sessionNameExistBesidesMySession(
5422
                                        $session_id,
5423
                                        $session_name
5424
                                    );
5425
                                    if (true === $sessionExistsBesidesMe) {
5426
                                        if ($debug) {
5427
                                            $message = "Skip Session. Error when update session Session #$session_id Name: '$session_name'. Other session has the same name. External id: ".$enreg['extra_'.$extraFieldId];
5428
                                            $logger->debug($message);
5429
                                            $report[] = $message;
5430
                                        }
5431
                                        continue;
5432
                                    } else {
5433
                                        if ($debug) {
5434
                                            $logger->debug(
5435
                                                "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]
5436
                                            );
5437
                                        }
5438
                                    }
5439
                                }
5440
                            }
5441
                        } else {
5442
                            $my_session_result = self::get_session_by_name($session_name);
5443
                            $session_id = $my_session_result['id'];
5444
                        }
5445
5446
                        if ($debug) {
5447
                            $logger->debug("Session #$session_id to be updated: '$session_name'");
5448
                        }
5449
5450
                        if ($session_id) {
5451
                            $sessionInfo = api_get_session_info($session_id);
5452
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
5453
5454
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5455
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
5456
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
5457
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
5458
                                ) {
5459
                                    $params['coach_access_start_date'] = $coachBefore;
5460
                                }
5461
5462
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
5463
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
5464
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
5465
                                ) {
5466
                                    $params['coach_access_end_date'] = $coachAfter;
5467
                                }
5468
                            }
5469
5470
                            Database::update($tbl_session, $params, ['id = ?' => $session_id]);
5471
                            Database::delete(
5472
                                $tbl_session_user,
5473
                                ['session_id = ? AND relation_type = ?' => [$session_id, Session::GENERAL_COACH]]
5474
                            );
5475
                            Database::insert(
5476
                                $tbl_session_user,
5477
                                [
5478
                                    'relation_type' => Session::GENERAL_COACH,
5479
                                    'duration' => 0,
5480
                                    'registered_at' => api_get_utc_datetime(),
5481
                                    'user_id' => $coach_id,
5482
                                    'session_id' => $session_id,
5483
                                ]
5484
                            );
5485
5486
                            foreach ($enreg as $key => $value) {
5487
                                if ('extra_' == substr($key, 0, 6)) { //an extra field
5488
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5489
                                }
5490
                            }
5491
5492
                            if ($debug) {
5493
                                $logger->debug("Session updated #$session_id");
5494
                            }
5495
5496
                            // Delete session-user relation only for students
5497
                            $sql = "DELETE FROM $tbl_session_user
5498
                                    WHERE session_id = '$session_id' AND relation_type = ".Session::STUDENT;
5499
                            Database::query($sql);
5500
5501
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5502
                            Database::query($sql);
5503
5504
                            // Delete session-course-user relationships students and coaches.
5505
                            if ($updateCourseCoaches) {
5506
                                $sql = "DELETE FROM $tbl_session_course_user
5507
                                        WHERE session_id = '$session_id' AND status in (".Session::STUDENT.", ".Session::COURSE_COACH.")";
5508
                                Database::query($sql);
5509
                            } else {
5510
                                // Delete session-course-user relation ships *only* for students.
5511
                                $sql = "DELETE FROM $tbl_session_course_user
5512
                                        WHERE session_id = '$session_id' AND status = ".Session::STUDENT;
5513
                                Database::query($sql);
5514
                            }
5515
5516
                            if ($deleteOnlyCourseCoaches) {
5517
                                $sql = "DELETE FROM $tbl_session_course_user
5518
                                        WHERE session_id = '$session_id' AND status = ".Session::COURSE_COACH;
5519
                                Database::query($sql);
5520
                            }
5521
                        } else {
5522
                            if ($debug) {
5523
                                $logger->debug(
5524
                                    "Sessions - Session not found"
5525
                                );
5526
                            }
5527
                        }
5528
                    }
5529
                    $session_counter++;
5530
                }
5531
5532
                $sessionList[] = $session_id;
5533
5534
                // Adding the relationship "Session - User" for students
5535
                $userList = [];
5536
                if (is_array($users)) {
5537
                    $extraFieldValueCareer = new ExtraFieldValue('career');
5538
                    $careerList = isset($enreg['extra_careerid']) && !empty($enreg['extra_careerid']) ? $enreg['extra_careerid'] : [];
5539
                    $careerList = str_replace(['[', ']'], '', $careerList);
5540
                    if (!empty($careerList)) {
5541
                        $careerList = explode(',', $careerList);
5542
                        $finalCareerIdList = [];
5543
                        foreach ($careerList as $careerId) {
5544
                            $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
5545
                                'external_career_id',
5546
                                $careerId
5547
                            );
5548
                            if (isset($realCareerIdList['item_id'])) {
5549
                                $finalCareerIdList[] = $realCareerIdList['item_id'];
5550
                            }
5551
                        }
5552
                    }
5553
5554
                    foreach ($users as $user) {
5555
                        $user_id = UserManager::get_user_id_from_username($user);
5556
                        if (false !== $user_id) {
5557
                            if (!empty($finalCareerIdList)) {
5558
                                foreach ($finalCareerIdList as $careerId) {
5559
                                    UserManager::addUserCareer($user_id, $careerId);
5560
                                }
5561
                            }
5562
5563
                            $userList[] = $user_id;
5564
                            // Insert new users.
5565
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
5566
                                    user_id = '$user_id',
5567
                                    session_id = '$session_id',
5568
                                    registered_at = '".api_get_utc_datetime()."'";
5569
                            Database::query($sql);
5570
                            if ($debug) {
5571
                                $logger->debug("Adding User #$user_id ($user) to session #$session_id");
5572
                            }
5573
                            $user_counter++;
5574
                        }
5575
                    }
5576
                }
5577
5578
                if ($deleteUsersNotInList) {
5579
                    // Getting user in DB in order to compare to the new list.
5580
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
5581
                    if (!empty($usersListInDatabase)) {
5582
                        if (empty($userList)) {
5583
                            foreach ($usersListInDatabase as $userInfo) {
5584
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5585
                            }
5586
                        } else {
5587
                            foreach ($usersListInDatabase as $userInfo) {
5588
                                if (!in_array($userInfo['user_id'], $userList)) {
5589
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5590
                                }
5591
                            }
5592
                        }
5593
                    }
5594
                }
5595
5596
                // See BT#6449
5597
                $onlyAddFirstCoachOrTeacher = false;
5598
                if ($sessionWithCoursesModifier) {
5599
                    if (count($courses) >= 2) {
5600
                        // Only first teacher in course session;
5601
                        $onlyAddFirstCoachOrTeacher = true;
5602
                        // Remove all teachers from course.
5603
                        $removeAllTeachersFromCourse = false;
5604
                    }
5605
                }
5606
5607
                foreach ($courses as $course) {
5608
                    $courseArray = bracketsToArray($course);
5609
                    $course_code = $courseArray[0];
5610
5611
                    if (CourseManager::course_exists($course_code)) {
5612
                        $courseInfo = api_get_course_info($course_code);
5613
                        $courseId = $courseInfo['real_id'];
5614
5615
                        // Adding the course to a session.
5616
                        $sql = "INSERT IGNORE INTO $tbl_session_course
5617
                                SET c_id = '$courseId', session_id='$session_id'";
5618
                        Database::query($sql);
5619
5620
                        self::installCourse($session_id, $courseInfo['real_id']);
5621
5622
                        if ($debug) {
5623
                            $logger->debug("Adding course '$course_code' to session #$session_id");
5624
                        }
5625
5626
                        $course_counter++;
5627
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
5628
                        $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
5629
                        $course_users = explode(',', $course_users);
5630
                        $course_coaches = explode(',', $course_coaches);
5631
5632
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
5633
                        $addTeachersToSession = true;
5634
5635
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
5636
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
5637
                        }
5638
5639
                        // If any user provided for a course, use the users array.
5640
                        if (empty($course_users)) {
5641
                            if (!empty($userList)) {
5642
                                self::subscribe_users_to_session_course(
5643
                                    $userList,
5644
                                    $session_id,
5645
                                    $course_code
5646
                                );
5647
                                if ($debug) {
5648
                                    $msg = "Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
5649
                                    $logger->debug($msg);
5650
                                }
5651
                            }
5652
                        }
5653
5654
                        // Adding coaches to session course user.
5655
                        if (!empty($course_coaches)) {
5656
                            $savedCoaches = [];
5657
                            // only edit if add_teachers_to_sessions_courses is set.
5658
                            if ($addTeachersToSession) {
5659
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
5660
                                    // Adding course teachers as course session teachers.
5661
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
5662
                                        $course_code
5663
                                    );
5664
5665
                                    if (!empty($alreadyAddedTeachers)) {
5666
                                        $teachersToAdd = [];
5667
                                        foreach ($alreadyAddedTeachers as $user) {
5668
                                            $teachersToAdd[] = $user['username'];
5669
                                        }
5670
                                        $course_coaches = array_merge(
5671
                                            $course_coaches,
5672
                                            $teachersToAdd
5673
                                        );
5674
                                    }
5675
                                }
5676
5677
                                foreach ($course_coaches as $course_coach) {
5678
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5679
                                    if (false !== $coach_id) {
5680
                                        // Just insert new coaches
5681
                                        self::updateCoaches(
5682
                                            $session_id,
5683
                                            $courseId,
5684
                                            [$coach_id],
5685
                                            false
5686
                                        );
5687
5688
                                        if ($debug) {
5689
                                            $logger->debug("Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5690
                                        }
5691
                                        $savedCoaches[] = $coach_id;
5692
                                    } else {
5693
                                        $error_message .= get_lang('This user doesn\'t exist').' : '.$course_coach.$eol;
5694
                                    }
5695
                                }
5696
                            }
5697
5698
                            // Custom courses/session coaches
5699
                            $teacherToAdd = null;
5700
                            // Only one coach is added.
5701
                            if (true == $onlyAddFirstCoachOrTeacher) {
5702
                                if ($debug) {
5703
                                    $logger->debug("onlyAddFirstCoachOrTeacher : true");
5704
                                }
5705
5706
                                foreach ($course_coaches as $course_coach) {
5707
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5708
                                    if (false !== $coach_id) {
5709
                                        $teacherToAdd = $coach_id;
5710
                                        break;
5711
                                    }
5712
                                }
5713
5714
                                // Un subscribe everyone that's not in the list.
5715
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5716
                                if (!empty($teacherList)) {
5717
                                    foreach ($teacherList as $teacher) {
5718
                                        if ($teacherToAdd != $teacher['user_id']) {
5719
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5720
                                                    WHERE
5721
                                                        user_id = ".$teacher['user_id']." AND
5722
                                                        c_id = '".$courseId."'
5723
                                                    ";
5724
5725
                                            $result = Database::query($sql);
5726
                                            $rows = Database::num_rows($result);
5727
                                            if ($rows > 0) {
5728
                                                $userCourseData = Database::fetch_assoc($result);
5729
                                                if (!empty($userCourseData)) {
5730
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5731
                                                }
5732
                                            }
5733
5734
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5735
                                                    WHERE
5736
                                                        user_id = ".$teacher['user_id']." AND
5737
                                                        c_id = '".$courseInfo['real_id']."'
5738
                                                    ";
5739
5740
                                            $result = Database::query($sql);
5741
                                            while ($groupData = Database::fetch_assoc($result)) {
5742
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5743
                                            }
5744
5745
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5746
                                                    WHERE
5747
                                                        user_id = ".$teacher['user_id']." AND
5748
                                                        c_id = '".$courseInfo['real_id']."'
5749
                                                    ";
5750
5751
                                            $result = Database::query($sql);
5752
                                            while ($groupData = Database::fetch_assoc($result)) {
5753
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5754
                                            }
5755
5756
                                            CourseManager::unsubscribe_user(
5757
                                                $teacher['user_id'],
5758
                                                $course_code
5759
                                            );
5760
5761
                                            if ($debug) {
5762
                                                $logger->debug("Delete user #".$teacher['user_id']." from base course: $course_code");
5763
                                            }
5764
                                        }
5765
                                    }
5766
                                }
5767
5768
                                if (!empty($teacherToAdd)) {
5769
                                    self::updateCoaches(
5770
                                        $session_id,
5771
                                        $courseId,
5772
                                        [$teacherToAdd],
5773
                                        true
5774
                                    );
5775
5776
                                    if ($debug) {
5777
                                        $logger->debug("Add coach #$teacherToAdd to course $courseId and session $session_id");
5778
                                    }
5779
5780
                                    $userCourseCategory = '';
5781
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
5782
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
5783
                                    ) {
5784
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
5785
                                        $userCourseCategory = $courseUserData['user_course_cat'];
5786
                                    }
5787
5788
                                    CourseManager::subscribeUser(
5789
                                        $teacherToAdd,
5790
                                        $courseId,
5791
                                        COURSEMANAGER,
5792
                                        0,
5793
                                        $userCourseCategory
5794
                                    );
5795
5796
                                    if ($debug) {
5797
                                        $logger->debug("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
5798
                                    }
5799
5800
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
5801
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
5802
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
5803
                                    ) {
5804
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
5805
                                            GroupManager::subscribeUsers(
5806
                                                $teacherToAdd,
5807
                                                api_get_group_entity($data['group_id']),
5808
                                                $data['c_id']
5809
                                            );
5810
                                        }
5811
                                    }
5812
5813
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5814
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5815
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5816
                                    ) {
5817
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5818
                                            GroupManager::subscribeTutors(
5819
                                                $teacherToAdd,
5820
                                                api_get_group_entity($data['group_id']),
5821
                                                $data['c_id']
5822
                                            );
5823
                                        }
5824
                                    }
5825
                                }
5826
                            }
5827
5828
                            // See BT#6449#note-195
5829
                            // All coaches are added.
5830
                            if ($removeAllTeachersFromCourse) {
5831
                                if ($debug) {
5832
                                    $logger->debug("removeAllTeachersFromCourse true");
5833
                                }
5834
                                $teacherToAdd = null;
5835
                                foreach ($course_coaches as $course_coach) {
5836
                                    $coach_id = UserManager::get_user_id_from_username(
5837
                                        $course_coach
5838
                                    );
5839
                                    if (false !== $coach_id) {
5840
                                        $teacherToAdd[] = $coach_id;
5841
                                    }
5842
                                }
5843
5844
                                if (!empty($teacherToAdd)) {
5845
                                    // Deleting all course teachers and adding the only coach as teacher.
5846
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5847
5848
                                    if (!empty($teacherList)) {
5849
                                        foreach ($teacherList as $teacher) {
5850
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5851
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5852
                                                        WHERE
5853
                                                            user_id = ".$teacher['user_id']." AND
5854
                                                            c_id = '".$courseId."'
5855
                                                        ";
5856
5857
                                                $result = Database::query($sql);
5858
                                                $rows = Database::num_rows($result);
5859
                                                if ($rows > 0) {
5860
                                                    $userCourseData = Database::fetch_assoc($result);
5861
                                                    if (!empty($userCourseData)) {
5862
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5863
                                                    }
5864
                                                }
5865
5866
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5867
                                                        WHERE
5868
                                                            user_id = ".$teacher['user_id']." AND
5869
                                                            c_id = '".$courseInfo['real_id']."'
5870
                                                        ";
5871
5872
                                                $result = Database::query($sql);
5873
                                                while ($groupData = Database::fetch_assoc($result)) {
5874
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5875
                                                }
5876
5877
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5878
                                                        WHERE
5879
                                                            user_id = ".$teacher['user_id']." AND
5880
                                                            c_id = '".$courseInfo['real_id']."'
5881
                                                        ";
5882
5883
                                                $result = Database::query($sql);
5884
                                                while ($groupData = Database::fetch_assoc($result)) {
5885
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5886
                                                }
5887
5888
                                                CourseManager::unsubscribe_user(
5889
                                                    $teacher['user_id'],
5890
                                                    $course_code
5891
                                                );
5892
5893
                                                if ($debug) {
5894
                                                    $logger->debug("Delete user #".$teacher['user_id']." from base course: $course_code");
5895
                                                }
5896
                                            }
5897
                                        }
5898
                                    }
5899
5900
                                    foreach ($teacherToAdd as $teacherId) {
5901
                                        $userCourseCategory = '';
5902
                                        if (isset($teacherBackupList[$teacherId]) &&
5903
                                            isset($teacherBackupList[$teacherId][$course_code])
5904
                                        ) {
5905
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5906
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5907
                                        }
5908
5909
                                        CourseManager::subscribeUser(
5910
                                            $teacherId,
5911
                                            $courseInfo['real_id'],
5912
                                            COURSEMANAGER,
5913
                                            0,
5914
                                            $userCourseCategory
5915
                                        );
5916
5917
                                        if ($debug) {
5918
                                            $logger->debug("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5919
                                        }
5920
5921
                                        if (isset($groupBackup['user'][$teacherId]) &&
5922
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5923
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5924
                                        ) {
5925
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5926
                                                GroupManager::subscribeUsers(
5927
                                                    $teacherId,
5928
                                                    api_get_group_entity($data['group_id']),
5929
                                                    $data['c_id']
5930
                                                );
5931
                                            }
5932
                                        }
5933
5934
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5935
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5936
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5937
                                        ) {
5938
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5939
                                                GroupManager::subscribeTutors(
5940
                                                    $teacherId,
5941
                                                    api_get_group_entity($data['group_id']),
5942
                                                    $data['c_id']
5943
                                                );
5944
                                            }
5945
                                        }
5946
                                    }
5947
                                }
5948
                            }
5949
5950
                            // Continue default behaviour.
5951
                            if (false == $onlyAddFirstCoachOrTeacher) {
5952
                                // Checking one more time see BT#6449#note-149
5953
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
5954
                                // Update coaches if only there's 1 course see BT#6449#note-189
5955
                                if (empty($coaches) || 1 == count($courses)) {
5956
                                    foreach ($course_coaches as $course_coach) {
5957
                                        $course_coach = trim($course_coach);
5958
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
5959
                                        if (false !== $coach_id) {
5960
                                            // Just insert new coaches
5961
                                            self::updateCoaches(
5962
                                                $session_id,
5963
                                                $courseId,
5964
                                                [$coach_id],
5965
                                                false
5966
                                            );
5967
5968
                                            if ($debug) {
5969
                                                $logger->debug("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5970
                                            }
5971
                                            $savedCoaches[] = $coach_id;
5972
                                        } else {
5973
                                            $error_message .= get_lang('This user doesn\'t exist').' : '.$course_coach.$eol;
5974
                                        }
5975
                                    }
5976
                                }
5977
                            }
5978
                        }
5979
5980
                        // Adding Students, updating relationship "Session - Course - User".
5981
                        $course_users = array_filter($course_users);
5982
                        if (!empty($course_users)) {
5983
                            foreach ($course_users as $user) {
5984
                                $user_id = UserManager::get_user_id_from_username($user);
5985
5986
                                if (false !== $user_id) {
5987
                                    self::subscribe_users_to_session_course(
5988
                                        [$user_id],
5989
                                        $session_id,
5990
                                        $course_code
5991
                                    );
5992
                                    if ($debug) {
5993
                                        $logger->debug("Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5994
                                    }
5995
                                } else {
5996
                                    $error_message .= get_lang('This user doesn\'t exist').': '.$user.$eol;
5997
                                }
5998
                            }
5999
                        }
6000
                        $inserted_in_course[$course_code] = $courseInfo['title'];
6001
                    }
6002
                }
6003
                $access_url_id = api_get_current_access_url_id();
6004
                UrlManager::add_session_to_url($session_id, $access_url_id);
6005
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter'
6006
                        WHERE id = '$session_id'";
6007
                Database::query($sql);
6008
6009
                self::addClassesByName($session_id, $classes, false);
6010
6011
                if ($debug) {
6012
                    $logger->debug("End process session #$session_id -------------------- ");
6013
                }
6014
            }
6015
6016
            if (!empty($report)) {
6017
                if ($debug) {
6018
                    $logger->debug("--Summary--");
6019
                    foreach ($report as $line) {
6020
                        $logger->debug($line);
6021
                    }
6022
                }
6023
            }
6024
        }
6025
6026
        return [
6027
            'error_message' => $error_message,
6028
            'session_counter' => $session_counter,
6029
            'session_list' => $sessionList,
6030
        ];
6031
    }
6032
6033
    /**
6034
     * @param int $sessionId
6035
     * @param int $courseId
6036
     *
6037
     * @return array
6038
     */
6039
    public static function getCoachesByCourseSession($sessionId, $courseId)
6040
    {
6041
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6042
        $sessionId = (int) $sessionId;
6043
        $courseId = (int) $courseId;
6044
6045
        $sql = "SELECT user_id FROM $table
6046
                WHERE
6047
                    session_id = '$sessionId' AND
6048
                    c_id = '$courseId' AND
6049
                    status = ".Session::COURSE_COACH;
6050
        $result = Database::query($sql);
6051
6052
        $coaches = [];
6053
        if (Database::num_rows($result) > 0) {
6054
            while ($row = Database::fetch_array($result)) {
6055
                $coaches[] = $row['user_id'];
6056
            }
6057
        }
6058
6059
        return $coaches;
6060
    }
6061
6062
    /**
6063
     * @param int    $sessionId
6064
     * @param int    $courseId
6065
     * @param string $separator
6066
     *
6067
     * @return string
6068
     */
6069
    public static function getCoachesByCourseSessionToString(
6070
        $sessionId,
6071
        $courseId,
6072
        $separator = ''
6073
    ) {
6074
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
6075
        $list = [];
6076
        if (!empty($coaches)) {
6077
            foreach ($coaches as $coachId) {
6078
                $userInfo = api_get_user_info($coachId);
6079
                if ($userInfo) {
6080
                    $list[] = $userInfo['complete_name'];
6081
                }
6082
            }
6083
        }
6084
6085
        $separator = empty($separator) ? CourseManager::USER_SEPARATOR : $separator;
6086
6087
        return array_to_string($list, $separator);
6088
    }
6089
6090
    /**
6091
     * Get all coaches added in the session - course relationship.
6092
     *
6093
     * @param int $sessionId
6094
     *
6095
     * @return array
6096
     */
6097
    public static function getCoachesBySession($sessionId)
6098
    {
6099
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6100
        $sessionId = intval($sessionId);
6101
6102
        $sql = "SELECT DISTINCT user_id
6103
                FROM $table
6104
                WHERE session_id = '$sessionId' AND status = ".Session::COURSE_COACH;
6105
        $result = Database::query($sql);
6106
6107
        $coaches = [];
6108
        if (Database::num_rows($result) > 0) {
6109
            while ($row = Database::fetch_array($result)) {
6110
                $coaches[] = $row['user_id'];
6111
            }
6112
        }
6113
6114
        return $coaches;
6115
    }
6116
6117
    /**
6118
     * @param int $userId
6119
     *
6120
     * @return array
6121
     */
6122
    public static function getAllCoursesFromAllSessionFromDrh($userId)
6123
    {
6124
        $sessions = self::get_sessions_followed_by_drh($userId);
6125
        $coursesFromSession = [];
6126
        if (!empty($sessions)) {
6127
            foreach ($sessions as $session) {
6128
                $courseList = self::get_course_list_by_session_id($session['id']);
6129
                foreach ($courseList as $course) {
6130
                    $coursesFromSession[] = $course['code'];
6131
                }
6132
            }
6133
        }
6134
6135
        return $coursesFromSession;
6136
    }
6137
6138
    /**
6139
     * getAllCoursesFromAllSessions.
6140
     *
6141
     * @return array
6142
     */
6143
    public static function getAllCoursesFromAllSessions()
6144
    {
6145
        $sessions = self::get_sessions_list();
6146
        $coursesFromSession = [];
6147
        if (!empty($sessions)) {
6148
            foreach ($sessions as $session) {
6149
                $courseList = self::get_course_list_by_session_id($session['id']);
6150
                foreach ($courseList as $course) {
6151
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'].' - '.$course['title'].' ('.$session['title'].')';
6152
                }
6153
            }
6154
        }
6155
6156
        return $coursesFromSession;
6157
    }
6158
6159
    /**
6160
     * Return user id list or count of users depending of the $getCount parameter.
6161
     *
6162
     * @param string $status
6163
     * @param int    $userId
6164
     * @param bool   $getCount
6165
     * @param int    $from
6166
     * @param int    $numberItems
6167
     * @param string $column
6168
     * @param string $direction
6169
     * @param string $keyword
6170
     * @param string $active
6171
     * @param string $lastConnectionDate
6172
     * @param array  $sessionIdList
6173
     * @param array  $studentIdList
6174
     * @param int    $filterByStatus
6175
     *
6176
     * @return array|int
6177
     */
6178
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
6179
        $status,
6180
        $userId,
6181
        $getCount = false,
6182
        $from = null,
6183
        $numberItems = null,
6184
        $column = '',
6185
        $direction = 'asc',
6186
        $keyword = null,
6187
        $active = null,
6188
        $lastConnectionDate = null,
6189
        $sessionIdList = [],
6190
        $studentIdList = [],
6191
        $filterByStatus = null
6192
    ) {
6193
        $filterByStatus = (int) $filterByStatus;
6194
        $userId = (int) $userId;
6195
6196
        if (empty($column)) {
6197
            $column = 'u.lastname';
6198
            if (api_is_western_name_order()) {
6199
                $column = 'u.firstname';
6200
            }
6201
        }
6202
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
6203
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
6204
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
6205
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6206
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
6207
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
6208
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6209
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6210
6211
        $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : 'asc';
6212
        $column = Database::escape_string($column);
6213
6214
        $urlId = api_get_current_access_url_id();
6215
6216
        $sessionConditions = '';
6217
        $courseConditions = '';
6218
        $userConditions = ' AND u.active <> '.USER_SOFT_DELETED.' ';
6219
6220
        if (isset($active)) {
6221
            $active = (int) $active;
6222
            $userConditions .= " AND active = $active";
6223
        }
6224
6225
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
6226
        if (!empty($courseList)) {
6227
            $courseIdList = array_column($courseList, 'id');
6228
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
6229
        }
6230
6231
        $userConditionsFromDrh = '';
6232
6233
        // Classic DRH
6234
        if (empty($studentIdList)) {
6235
            $studentListSql = UserManager::get_users_followed_by_drh(
6236
                $userId,
6237
                $filterByStatus,
6238
                true,
6239
                false
6240
            );
6241
            if (!empty($studentListSql)) {
6242
                $studentIdList = array_keys($studentListSql);
6243
                $studentListSql = "'".implode("','", $studentIdList)."'";
6244
            }
6245
        } else {
6246
            $studentIdList = array_map('intval', $studentIdList);
6247
            $studentListSql = "'".implode("','", $studentIdList)."'";
6248
        }
6249
        if (!empty($studentListSql)) {
6250
            $userConditionsFromDrh = " AND u.id IN ($studentListSql) ";
6251
        }
6252
6253
        switch ($status) {
6254
            case 'admin':
6255
            case 'drh':
6256
                break;
6257
            case 'drh_all':
6258
                // Show all by DRH
6259
                if (empty($sessionIdList)) {
6260
                    $sessionListFollowed = self::get_sessions_followed_by_drh(
6261
                        $userId,
6262
                        null,
6263
                        null,
6264
                        false,
6265
                        true
6266
                    );
6267
6268
                    if (!empty($sessionListFollowed)) {
6269
                        $sessionIdList = array_column($sessionListFollowed, 'id');
6270
                    }
6271
                }
6272
6273
                if (!empty($sessionIdList)) {
6274
                    $sessionIdList = array_map('intval', $sessionIdList);
6275
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
6276
                    $sessionConditions = " AND s.id IN ($sessionsListSql) ";
6277
                }
6278
6279
                break;
6280
            case 'teacher':
6281
            case 'session_admin':
6282
                $generalCoachedSessions = array_map(
6283
                    fn(Session $session) => $session->getId(),
6284
                    api_get_user_entity($userId)->getSessionsAsGeneralCoach()
6285
                );
6286
6287
                $sessionConditions = " AND s.IN (".implode(',', $generalCoachedSessions).") ";
6288
                $userConditionsFromDrh = '';
6289
                break;
6290
        }
6291
6292
        $select = 'SELECT DISTINCT u.*, u.id as user_id';
6293
        $masterSelect = 'SELECT DISTINCT id, id as user_id FROM ';
6294
6295
        if ($getCount) {
6296
            $select = 'SELECT DISTINCT u.id, u.id as user_id';
6297
            $masterSelect = 'SELECT COUNT(DISTINCT(id)) as count FROM ';
6298
        }
6299
6300
        if (!empty($filterByStatus)) {
6301
            $userConditions .= " AND u.status = $filterByStatus";
6302
        }
6303
6304
        if (!empty($lastConnectionDate)) {
6305
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
6306
            $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
6307
        }
6308
6309
        if (!empty($keyword)) {
6310
            $keyword = Database::escape_string($keyword);
6311
            $userConditions .= " AND (
6312
                u.username LIKE '%$keyword%' OR
6313
                u.firstname LIKE '%$keyword%' OR
6314
                u.lastname LIKE '%$keyword%' OR
6315
                u.official_code LIKE '%$keyword%' OR
6316
                u.email LIKE '%$keyword%'
6317
            )";
6318
        }
6319
6320
        $where = " WHERE
6321
                   access_url_id = $urlId
6322
                   $userConditions
6323
        ";
6324
6325
        $userUnion = '';
6326
        if (!empty($userConditionsFromDrh)) {
6327
            $userUnion = "
6328
            UNION (
6329
                $select
6330
                FROM $tbl_user u
6331
                INNER JOIN $tbl_user_rel_access_url url
6332
                ON (url.user_id = u.id)
6333
                $where
6334
                $userConditionsFromDrh
6335
            )";
6336
        }
6337
6338
        $sql = "$masterSelect (
6339
                ($select
6340
                FROM $tbl_session s
6341
                    INNER JOIN $tbl_session_rel_access_url url
6342
                    ON (url.session_id = s.id)
6343
                    INNER JOIN $tbl_session_rel_course_rel_user su
6344
                    ON (s.id = su.session_id)
6345
                    INNER JOIN $tbl_user u
6346
                    ON (u.id = su.user_id)
6347
                    $where
6348
                    $sessionConditions
6349
                    $userConditionsFromDrh
6350
                ) UNION (
6351
                    $select
6352
                    FROM $tbl_course c
6353
                    INNER JOIN $tbl_course_rel_access_url url
6354
                    ON (url.c_id = c.id)
6355
                    INNER JOIN $tbl_course_user cu
6356
                    ON (cu.c_id = c.id)
6357
                    INNER JOIN $tbl_user u
6358
                    ON (u.id = cu.user_id)
6359
                    $where
6360
                    $courseConditions
6361
                    $userConditionsFromDrh
6362
                ) $userUnion
6363
                ) as t1
6364
                ";
6365
6366
        if ($getCount) {
6367
            $result = Database::query($sql);
6368
6369
            $count = 0;
6370
            if (Database::num_rows($result)) {
6371
                $rows = Database::fetch_array($result);
6372
                $count = $rows['count'];
6373
            }
6374
6375
            return $count;
6376
        }
6377
6378
        if (!empty($column) && !empty($direction)) {
6379
            $column = str_replace('u.', '', $column);
6380
            $sql .= " ORDER BY `$column` $direction ";
6381
        }
6382
6383
        $limitCondition = '';
6384
        if (isset($from) && isset($numberItems)) {
6385
            $from = (int) $from;
6386
            $numberItems = (int) $numberItems;
6387
            $limitCondition = "LIMIT $from, $numberItems";
6388
        }
6389
6390
        $sql .= $limitCondition;
6391
        $result = Database::query($sql);
6392
6393
        return Database::store_result($result);
6394
    }
6395
6396
    /**
6397
     * @param int   $sessionId
6398
     * @param int   $courseId
6399
     * @param array $coachList
6400
     * @param bool  $deleteCoachesNotInList
6401
     */
6402
    public static function updateCoaches(
6403
        $sessionId,
6404
        $courseId,
6405
        $coachList,
6406
        $deleteCoachesNotInList = false
6407
    ) {
6408
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
6409
6410
        if (!empty($coachList)) {
6411
            foreach ($coachList as $userId) {
6412
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
6413
            }
6414
        }
6415
6416
        if ($deleteCoachesNotInList) {
6417
            if (!empty($coachList)) {
6418
                $coachesToDelete = array_diff($currentCoaches, $coachList);
6419
            } else {
6420
                $coachesToDelete = $currentCoaches;
6421
            }
6422
6423
            if (!empty($coachesToDelete)) {
6424
                foreach ($coachesToDelete as $userId) {
6425
                    self::set_coach_to_course_session(
6426
                        $userId,
6427
                        $sessionId,
6428
                        $courseId,
6429
                        true
6430
                    );
6431
                }
6432
            }
6433
        }
6434
    }
6435
6436
    /**
6437
     * @param array $sessions
6438
     * @param array $sessionsDestination
6439
     *
6440
     * @return array
6441
     */
6442
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
6443
    {
6444
        $messages = [];
6445
        if (!empty($sessions)) {
6446
            foreach ($sessions as $sessionId) {
6447
                $sessionInfo = self::fetch($sessionId);
6448
                $userList = self::get_users_by_session($sessionId, 0);
6449
                if (!empty($userList)) {
6450
                    $newUserList = [];
6451
                    $userToString = null;
6452
                    foreach ($userList as $userInfo) {
6453
                        $newUserList[] = $userInfo['user_id'];
6454
                        $userToString .= $userInfo['firstname'].' '.$userInfo['lastname'].'<br />';
6455
                    }
6456
6457
                    if (!empty($sessionsDestination)) {
6458
                        foreach ($sessionsDestination as $sessionDestinationId) {
6459
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
6460
                            $messages[] = Display::return_message(
6461
                                sprintf(
6462
                                    get_lang(
6463
                                        'AddingStudentsFromSessionXToSessionY'
6464
                                    ),
6465
                                    $sessionInfo['title'],
6466
                                    $sessionDestinationInfo['title']
6467
                                ),
6468
                                'info',
6469
                                false
6470
                            );
6471
                            if ($sessionId == $sessionDestinationId) {
6472
                                $messages[] = Display::return_message(
6473
                                    sprintf(
6474
                                        get_lang('Session %s skipped'),
6475
                                        $sessionDestinationId
6476
                                    ),
6477
                                    'warning',
6478
                                    false
6479
                                );
6480
                                continue;
6481
                            }
6482
                            $messages[] = Display::return_message(get_lang('Learners list').'<br />'.$userToString, 'info', false);
6483
                            self::subscribeUsersToSession(
6484
                                $sessionDestinationId,
6485
                                $newUserList,
6486
                                SESSION_VISIBLE_READ_ONLY,
6487
                                false
6488
                            );
6489
                        }
6490
                    } else {
6491
                        $messages[] = Display::return_message(get_lang('No destination session provided'), 'warning');
6492
                    }
6493
                } else {
6494
                    $messages[] = Display::return_message(
6495
                        get_lang('No student found for the session').' #'.$sessionInfo['title'],
6496
                        'warning'
6497
                    );
6498
                }
6499
            }
6500
        } else {
6501
            $messages[] = Display::return_message(get_lang('No data available'), 'warning');
6502
        }
6503
6504
        return $messages;
6505
    }
6506
6507
    /**
6508
     * Assign coaches of a session(s) as teachers to a given course (or courses).
6509
     *
6510
     * @param array A list of session IDs
6511
     * @param array A list of course IDs
6512
     *
6513
     * @return string
6514
     */
6515
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
6516
    {
6517
        $coachesPerSession = [];
6518
        foreach ($sessions as $sessionId) {
6519
            $coaches = self::getCoachesBySession($sessionId);
6520
            $coachesPerSession[$sessionId] = $coaches;
6521
        }
6522
6523
        $result = [];
6524
6525
        if (!empty($courses)) {
6526
            foreach ($courses as $courseId) {
6527
                $courseInfo = api_get_course_info_by_id($courseId);
6528
                foreach ($coachesPerSession as $sessionId => $coachList) {
6529
                    CourseManager::updateTeachers(
6530
                        $courseInfo,
6531
                        $coachList,
6532
                        false,
6533
                        false,
6534
                        false
6535
                    );
6536
                    $result[$courseInfo['code']][$sessionId] = $coachList;
6537
                }
6538
            }
6539
        }
6540
        $sessionUrl = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session=';
6541
        $htmlResult = null;
6542
6543
        if (!empty($result)) {
6544
            foreach ($result as $courseCode => $data) {
6545
                $url = api_get_course_url($courseCode);
6546
                $htmlResult .= sprintf(
6547
                    get_lang('Coaches subscribed as teachers in course %s'),
6548
                    Display::url($courseCode, $url, ['target' => '_blank'])
6549
                );
6550
                foreach ($data as $sessionId => $coachList) {
6551
                    $sessionInfo = self::fetch($sessionId);
6552
                    $htmlResult .= '<br />';
6553
                    $htmlResult .= Display::url(
6554
                        get_lang('Session').': '.$sessionInfo['title'].' <br />',
6555
                        $sessionUrl.$sessionId,
6556
                        ['target' => '_blank']
6557
                    );
6558
                    $teacherList = [];
6559
                    foreach ($coachList as $coachId) {
6560
                        $userInfo = api_get_user_info($coachId);
6561
                        $teacherList[] = $userInfo['complete_name'];
6562
                    }
6563
                    if (!empty($teacherList)) {
6564
                        $htmlResult .= implode(', ', $teacherList);
6565
                    } else {
6566
                        $htmlResult .= get_lang('Nothing to add');
6567
                    }
6568
                }
6569
                $htmlResult .= '<br />';
6570
            }
6571
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
6572
        }
6573
6574
        return $htmlResult;
6575
    }
6576
6577
    /**
6578
     * @param string $keyword
6579
     * @param string $active
6580
     * @param string $lastConnectionDate
6581
     * @param array  $sessionIdList
6582
     * @param array  $studentIdList
6583
     * @param int    $filterUserStatus   STUDENT|COURSEMANAGER constants
6584
     *
6585
     * @return array|int
6586
     */
6587
    public static function getCountUserTracking(
6588
        $keyword = null,
6589
        $active = null,
6590
        $lastConnectionDate = null,
6591
        $sessionIdList = [],
6592
        $studentIdList = [],
6593
        $filterUserStatus = null
6594
    ) {
6595
        $userId = api_get_user_id();
6596
        $drhLoaded = false;
6597
6598
        if (api_is_drh()) {
6599
            if (api_drh_can_access_all_session_content()) {
6600
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
6601
                    'drh_all',
6602
                    $userId,
6603
                    true,
6604
                    null,
6605
                    null,
6606
                    null,
6607
                    null,
6608
                    $keyword,
6609
                    $active,
6610
                    $lastConnectionDate,
6611
                    $sessionIdList,
6612
                    $studentIdList,
6613
                    $filterUserStatus
6614
                );
6615
                $drhLoaded = true;
6616
            }
6617
        }
6618
6619
        if (false == $drhLoaded) {
6620
            $count = UserManager::getUsersFollowedByUser(
6621
                $userId,
6622
                $filterUserStatus,
6623
                false,
6624
                false,
6625
                true,
6626
                null,
6627
                null,
6628
                null,
6629
                null,
6630
                $active,
6631
                $lastConnectionDate,
6632
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
6633
                $keyword
6634
            );
6635
        }
6636
6637
        return $count;
6638
    }
6639
6640
    /**
6641
     * Get teachers followed by a user.
6642
     *
6643
     * @param int    $userId
6644
     * @param int    $active
6645
     * @param string $lastConnectionDate
6646
     * @param bool   $getCount
6647
     * @param array  $sessionIdList
6648
     *
6649
     * @return array|int
6650
     */
6651
    public static function getTeacherTracking(
6652
        $userId,
6653
        $active = 1,
6654
        $lastConnectionDate = null,
6655
        $getCount = false,
6656
        $sessionIdList = []
6657
    ) {
6658
        $teacherListId = [];
6659
        if (api_is_drh() || api_is_platform_admin()) {
6660
            // Followed teachers by drh
6661
            if (api_drh_can_access_all_session_content()) {
6662
                if (empty($sessionIdList)) {
6663
                    $sessions = self::get_sessions_followed_by_drh($userId);
6664
                    $sessionIdList = [];
6665
                    foreach ($sessions as $session) {
6666
                        $sessionIdList[] = $session['id'];
6667
                    }
6668
                }
6669
6670
                $sessionIdList = array_map('intval', $sessionIdList);
6671
                $sessionToString = implode("', '", $sessionIdList);
6672
6673
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
6674
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6675
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6676
6677
                // Select the teachers.
6678
                $sql = "SELECT DISTINCT(cu.user_id)
6679
                        FROM $course c
6680
                        INNER JOIN $sessionCourse src
6681
                        ON c.id = src.c_id
6682
                        INNER JOIN $courseUser cu
6683
                        ON (cu.c_id = c.id)
6684
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
6685
                $result = Database::query($sql);
6686
                while ($row = Database::fetch_assoc($result)) {
6687
                    $teacherListId[$row['user_id']] = $row['user_id'];
6688
                }
6689
            } else {
6690
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
6691
                foreach ($teacherResult as $userInfo) {
6692
                    $teacherListId[] = $userInfo['user_id'];
6693
                }
6694
            }
6695
        }
6696
6697
        if (!empty($teacherListId)) {
6698
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6699
6700
            $select = "SELECT DISTINCT u.* ";
6701
            if ($getCount) {
6702
                $select = "SELECT count(DISTINCT(u.id)) as count";
6703
            }
6704
6705
            $sql = "$select FROM $tableUser u";
6706
6707
            if (!empty($lastConnectionDate)) {
6708
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6709
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
6710
            }
6711
            $active = intval($active);
6712
            $teacherListId = implode("','", $teacherListId);
6713
            $where = " WHERE u.active = $active AND u.id IN ('$teacherListId') ";
6714
6715
            if (!empty($lastConnectionDate)) {
6716
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
6717
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
6718
            }
6719
6720
            $sql .= $where;
6721
            $result = Database::query($sql);
6722
            if (Database::num_rows($result)) {
6723
                if ($getCount) {
6724
                    $row = Database::fetch_array($result);
6725
6726
                    return $row['count'];
6727
                } else {
6728
                    return Database::store_result($result, 'ASSOC');
6729
                }
6730
            }
6731
        }
6732
6733
        return 0;
6734
    }
6735
6736
    /**
6737
     * Get the list of course tools that have to be dealt with in case of
6738
     * registering any course to a session.
6739
     *
6740
     * @return array The list of tools to be dealt with (literal names)
6741
     */
6742
    public static function getCourseToolToBeManaged()
6743
    {
6744
        return [
6745
            'courseDescription',
6746
            'courseIntroduction',
6747
        ];
6748
    }
6749
6750
    /**
6751
     * Calls the methods bound to each tool when a course is registered into a session.
6752
     *
6753
     * @param int $sessionId
6754
     * @param int $courseId
6755
     *
6756
     * @return bool
6757
     */
6758
    public static function installCourse($sessionId, $courseId)
6759
    {
6760
        return true;
6761
        $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...
6762
6763
        foreach ($toolList as $tool) {
6764
            $method = 'add'.$tool;
6765
            if (method_exists(get_class(), $method)) {
6766
                self::$method($sessionId, $courseId);
6767
            }
6768
        }
6769
    }
6770
6771
    /**
6772
     * Calls the methods bound to each tool when a course is unregistered from
6773
     * a session.
6774
     *
6775
     * @param int $sessionId
6776
     * @param int $courseId
6777
     */
6778
    public static function unInstallCourse($sessionId, $courseId)
6779
    {
6780
        return true;
6781
        $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...
6782
6783
        foreach ($toolList as $tool) {
6784
            $method = 'remove'.$tool;
6785
            if (method_exists(get_class(), $method)) {
6786
                self::$method($sessionId, $courseId);
6787
            }
6788
        }
6789
    }
6790
6791
    /**
6792
     * @param array $userSessionList        format see self::importSessionDrhCSV()
6793
     * @param bool  $sendEmail
6794
     * @param bool  $removeOldRelationShips
6795
     */
6796
    public static function subscribeDrhToSessionList(
6797
        $userSessionList,
6798
        $sendEmail,
6799
        $removeOldRelationShips
6800
    ) {
6801
        if (!empty($userSessionList)) {
6802
            foreach ($userSessionList as $userId => $data) {
6803
                $sessionList = [];
6804
                foreach ($data['session_list'] as $sessionInfo) {
6805
                    $sessionList[] = $sessionInfo['session_id'];
6806
                }
6807
                $userInfo = $data['user_info'];
6808
                self::subscribeSessionsToDrh(
6809
                    $userInfo,
6810
                    $sessionList,
6811
                    $sendEmail,
6812
                    $removeOldRelationShips
6813
                );
6814
            }
6815
        }
6816
    }
6817
6818
    /**
6819
     * @param array $userSessionList format see self::importSessionDrhCSV()
6820
     *
6821
     * @return string
6822
     */
6823
    public static function checkSubscribeDrhToSessionList($userSessionList)
6824
    {
6825
        $message = null;
6826
        if (!empty($userSessionList)) {
6827
            if (!empty($userSessionList)) {
6828
                foreach ($userSessionList as $userId => $data) {
6829
                    $userInfo = $data['user_info'];
6830
6831
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
6832
                    if (!empty($sessionListSubscribed)) {
6833
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
6834
                    }
6835
6836
                    $sessionList = [];
6837
                    if (!empty($data['session_list'])) {
6838
                        foreach ($data['session_list'] as $sessionInfo) {
6839
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
6840
                                $sessionList[] = $sessionInfo['session_info']['title'];
6841
                            }
6842
                        }
6843
                    }
6844
6845
                    $message .= '<strong>'.get_lang('User').'</strong>: ';
6846
                    $message .= $userInfo['complete_name_with_username'].' <br />';
6847
6848
                    if (!in_array($userInfo['status'], [DRH]) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6849
                        $message .= get_lang('Users must have the HR director role').'<br />';
6850
                        continue;
6851
                    }
6852
6853
                    if (!empty($sessionList)) {
6854
                        $message .= '<strong>'.get_lang('Course sessions').':</strong> <br />';
6855
                        $message .= implode(', ', $sessionList).'<br /><br />';
6856
                    } else {
6857
                        $message .= get_lang('No session provided').' <br /><br />';
6858
                    }
6859
                }
6860
            }
6861
        }
6862
6863
        return $message;
6864
    }
6865
6866
    /**
6867
     * @param string $file
6868
     * @param bool   $sendEmail
6869
     * @param bool   $removeOldRelationShips
6870
     *
6871
     * @return string
6872
     */
6873
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6874
    {
6875
        $list = Import::csv_reader($file);
6876
6877
        if (!empty($list)) {
6878
            $userSessionList = [];
6879
            foreach ($list as $data) {
6880
                $sessionInfo = [];
6881
                if (isset($data['SessionId'])) {
6882
                    $sessionInfo = api_get_session_info($data['SessionId']);
6883
                }
6884
6885
                if (isset($data['SessionName']) && empty($sessionInfo)) {
6886
                $sessionInfo = self::get_session_by_name($data['SessionName']);
6887
                }
6888
6889
                if (empty($sessionInfo)) {
6890
                    $sessionData = isset($data['SessionName']) ? $data['SessionName'] : $data['SessionId'];
6891
                    Display::addFlash(
6892
                        Display::return_message(get_lang('SessionNotFound').' - '.$sessionData, 'warning')
6893
                    );
6894
                    continue;
6895
                }
6896
                $userList = explode(',', $data['Username']);
6897
6898
                foreach ($userList as $username) {
6899
                    $userInfo = api_get_user_info_from_username($username);
6900
6901
                if (empty($userInfo)) {
6902
                        Display::addFlash(
6903
                            Display::return_message(get_lang('UserDoesNotExist').' - '.$username, 'warning')
6904
                        );
6905
                        continue;
6906
                }
6907
6908
                if (!empty($userInfo) && !empty($sessionInfo)) {
6909
                    $userSessionList[$userInfo['user_id']]['session_list'][] = [
6910
                        'session_id' => $sessionInfo['id'],
6911
                        'session_info' => $sessionInfo,
6912
                    ];
6913
                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6914
                    }
6915
                }
6916
            }
6917
6918
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6919
6920
            return self::checkSubscribeDrhToSessionList($userSessionList);
6921
        }
6922
    }
6923
6924
    /**
6925
     * Courses re-ordering in resume_session.php flag see BT#8316.
6926
     */
6927
    public static function orderCourseIsEnabled()
6928
    {
6929
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6930
        if ('true' === $sessionCourseOrder) {
6931
            return true;
6932
        }
6933
6934
        return false;
6935
    }
6936
6937
    /**
6938
     * @param string $direction (up/down)
6939
     * @param int    $sessionId
6940
     * @param int    $courseId
6941
     *
6942
     * @return bool
6943
     */
6944
    public static function move($direction, $sessionId, $courseId)
6945
    {
6946
        if (!self::orderCourseIsEnabled()) {
6947
            return false;
6948
        }
6949
6950
        $sessionId = intval($sessionId);
6951
        $courseId = intval($courseId);
6952
6953
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6954
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6955
6956
        $position = [];
6957
        $count = 0;
6958
        foreach ($courseList as $course) {
6959
            if ('' == $course['position']) {
6960
                $course['position'] = $count;
6961
            }
6962
            $position[$course['code']] = $course['position'];
6963
            // Saving current order.
6964
            $sql = "UPDATE $table SET position = $count
6965
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
6966
            Database::query($sql);
6967
            $count++;
6968
        }
6969
6970
        // Loading new positions.
6971
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6972
6973
        $found = false;
6974
6975
        switch ($direction) {
6976
            case 'up':
6977
                $courseList = array_reverse($courseList);
6978
                break;
6979
            case 'down':
6980
                break;
6981
        }
6982
6983
        foreach ($courseList as $course) {
6984
            if ($found) {
6985
                $nextId = $course['real_id'];
6986
                $nextOrder = $course['position'];
6987
                break;
6988
            }
6989
6990
            if ($courseId == $course['real_id']) {
6991
                $thisCourseCode = $course['real_id'];
6992
                $thisOrder = $course['position'];
6993
                $found = true;
6994
            }
6995
        }
6996
6997
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
6998
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
6999
        Database::query($sql1);
7000
7001
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
7002
                 WHERE session_id = $sessionId AND c_id = $nextId";
7003
        Database::query($sql2);
7004
7005
        return true;
7006
    }
7007
7008
    /**
7009
     * @param int $sessionId
7010
     * @param int $courseId
7011
     *
7012
     * @return bool
7013
     */
7014
    public static function moveUp($sessionId, $courseId)
7015
    {
7016
        return self::move('up', $sessionId, $courseId);
7017
    }
7018
7019
    /**
7020
     * @param int    $sessionId
7021
     * @param string $courseCode
7022
     *
7023
     * @return bool
7024
     */
7025
    public static function moveDown($sessionId, $courseCode)
7026
    {
7027
        return self::move('down', $sessionId, $courseCode);
7028
    }
7029
7030
    /**
7031
     * Use the session duration to allow/block user access see BT#8317
7032
     * Needs these DB changes
7033
     * ALTER TABLE session ADD COLUMN duration int;
7034
     * ALTER TABLE session_rel_user ADD COLUMN duration int;.
7035
     */
7036
    public static function durationPerUserIsEnabled()
7037
    {
7038
        return api_get_configuration_value('session_duration_feature');
7039
    }
7040
7041
    /**
7042
     * Returns the number of days the student has left in a session when using
7043
     * sessions durations.
7044
     *
7045
     * @param int $userId
7046
     *
7047
     * @return int
7048
     */
7049
    public static function getDayLeftInSession(array $sessionInfo, $userId)
7050
    {
7051
        $sessionId = $sessionInfo['id'];
7052
        $subscription = self::getUserSession($userId, $sessionId);
7053
        $duration = empty($subscription['duration'])
7054
            ? $sessionInfo['duration']
7055
            : $sessionInfo['duration'] + $subscription['duration'];
7056
7057
        // Get an array with the details of the first access of the student to
7058
        // this session
7059
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
7060
            $sessionId,
7061
            $userId
7062
        );
7063
7064
        $currentTime = time();
7065
7066
        // If no previous access, return false
7067
        if (0 == count($courseAccess)) {
7068
            return $duration;
7069
        }
7070
7071
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
7072
        $endDateInSeconds = $firstAccess + $duration * 24 * 60 * 60;
7073
        $leftDays = round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
7074
7075
        return $leftDays;
7076
    }
7077
7078
    /**
7079
     * @param int $duration
7080
     * @param int $userId
7081
     * @param int $sessionId
7082
     *
7083
     * @return bool
7084
     */
7085
    public static function editUserSessionDuration($duration, $userId, $sessionId)
7086
    {
7087
        $duration = (int) $duration;
7088
        $userId = (int) $userId;
7089
        $sessionId = (int) $sessionId;
7090
7091
        if (empty($userId) || empty($sessionId)) {
7092
            return false;
7093
        }
7094
7095
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7096
        $parameters = ['duration' => $duration];
7097
        $where = ['session_id = ? AND user_id = ? ' => [$sessionId, $userId]];
7098
        Database::update($table, $parameters, $where);
7099
7100
        return true;
7101
    }
7102
7103
    /**
7104
     * Gets one row from the session_rel_user table.
7105
     *
7106
     * @param int $userId
7107
     * @param int $sessionId
7108
     *
7109
     * @return array
7110
     */
7111
    public static function getUserSession($userId, $sessionId)
7112
    {
7113
        $userId = (int) $userId;
7114
        $sessionId = (int) $sessionId;
7115
7116
        if (empty($userId) || empty($sessionId)) {
7117
            return false;
7118
        }
7119
7120
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7121
        $sql = "SELECT * FROM $table
7122
                WHERE session_id = $sessionId AND user_id = $userId";
7123
        $result = Database::query($sql);
7124
        $values = [];
7125
        if (Database::num_rows($result)) {
7126
            $values = Database::fetch_assoc($result);
7127
        }
7128
7129
        return $values;
7130
    }
7131
7132
    /**
7133
     * Check if user is subscribed inside a session as student.
7134
     *
7135
     * @param int $sessionId The session id
7136
     * @param int $userId    The user id
7137
     *
7138
     * @return bool Whether is subscribed
7139
     */
7140
    public static function isUserSubscribedAsStudent($sessionId, $userId)
7141
    {
7142
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7143
        $sessionId = (int) $sessionId;
7144
        $userId = (int) $userId;
7145
7146
        // COUNT(1) actually returns the number of rows from the table (as if
7147
        // counting the results from the first column)
7148
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7149
                WHERE
7150
                    session_id = $sessionId AND
7151
                    user_id = $userId AND
7152
                    relation_type = ".Session::STUDENT;
7153
7154
        $result = Database::fetch_assoc(Database::query($sql));
7155
7156
        if (!empty($result) && $result['qty'] > 0) {
7157
            return true;
7158
        }
7159
7160
        return false;
7161
    }
7162
7163
    /**
7164
     * Check if user is subscribed inside a session as a HRM.
7165
     *
7166
     * @param int $sessionId The session id
7167
     * @param int $userId    The user id
7168
     *
7169
     * @return bool Whether is subscribed
7170
     */
7171
    public static function isUserSubscribedAsHRM($sessionId, $userId)
7172
    {
7173
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7174
7175
        $sessionId = (int) $sessionId;
7176
        $userId = (int) $userId;
7177
7178
        // COUNT(1) actually returns the number of rows from the table (as if
7179
        // counting the results from the first column)
7180
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7181
                WHERE
7182
                    session_id = $sessionId AND
7183
                    user_id = $userId AND
7184
                    relation_type = ".Session::DRH;
7185
7186
        $result = Database::fetch_assoc(Database::query($sql));
7187
7188
        if (!empty($result) && $result['qty'] > 0) {
7189
            return true;
7190
        }
7191
7192
        return false;
7193
    }
7194
7195
    /**
7196
     * Get the session coached by a user (general coach and course-session coach).
7197
     *
7198
     * @param int  $coachId                       The coach id
7199
     * @param bool $checkSessionRelUserVisibility Check the session visibility
7200
     * @param bool $asPlatformAdmin               The user is a platform admin and we want all sessions
7201
     *
7202
     * @return array The session list
7203
     */
7204
    public static function getSessionsCoachedByUser(
7205
        $coachId,
7206
        $checkSessionRelUserVisibility = false,
7207
        $asPlatformAdmin = false
7208
    ) {
7209
        // Get all sessions where $coachId is the general coach
7210
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
7211
        // Get all sessions where $coachId is the course - session coach
7212
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
7213
        $sessionsByCoach = [];
7214
        if (!empty($courseSessionList)) {
7215
            foreach ($courseSessionList as $userCourseSubscription) {
7216
                $session = $userCourseSubscription->getSession();
7217
                $sessionsByCoach[$session->getId()] = api_get_session_info(
7218
                    $session->getId()
7219
                );
7220
            }
7221
        }
7222
7223
        if (!empty($sessionsByCoach)) {
7224
            $sessions = array_merge($sessions, $sessionsByCoach);
7225
        }
7226
7227
        // Remove repeated sessions
7228
        if (!empty($sessions)) {
7229
            $cleanSessions = [];
7230
            foreach ($sessions as $session) {
7231
                $cleanSessions[$session['id']] = $session;
7232
            }
7233
            $sessions = $cleanSessions;
7234
        }
7235
7236
        if ($checkSessionRelUserVisibility) {
7237
            if (!empty($sessions)) {
7238
                $newSessions = [];
7239
                foreach ($sessions as $session) {
7240
                    $visibility = api_get_session_visibility($session['id']);
7241
                    if (SESSION_INVISIBLE == $visibility) {
7242
                        continue;
7243
                    }
7244
                    $newSessions[] = $session;
7245
                }
7246
                $sessions = $newSessions;
7247
            }
7248
        }
7249
7250
        return $sessions;
7251
    }
7252
7253
    /**
7254
     * Check if the course belongs to the session.
7255
     *
7256
     * @param int    $sessionId  The session id
7257
     * @param string $courseCode The course code
7258
     *
7259
     * @return bool
7260
     */
7261
    public static function sessionHasCourse($sessionId, $courseCode)
7262
    {
7263
        $sessionId = (int) $sessionId;
7264
        $courseCode = Database::escape_string($courseCode);
7265
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7266
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7267
7268
        $sql = "SELECT COUNT(1) AS qty
7269
                FROM $courseTable c
7270
                INNER JOIN $sessionRelCourseTable src
7271
                ON c.id = src.c_id
7272
                WHERE src.session_id = $sessionId
7273
                AND c.code = '$courseCode'  ";
7274
7275
        $result = Database::query($sql);
7276
7277
        if (false !== $result) {
7278
            $data = Database::fetch_assoc($result);
7279
7280
            if ($data['qty'] > 0) {
7281
                return true;
7282
            }
7283
        }
7284
7285
        return false;
7286
    }
7287
7288
    /**
7289
     * Calculate the total user time in the platform.
7290
     *
7291
     * @param int    $userId The user id
7292
     * @param string $from   Optional. From date
7293
     * @param string $until  Optional. Until date
7294
     *
7295
     * @return string The time (hh:mm:ss)
7296
     */
7297
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
7298
    {
7299
        $userId = (int) $userId;
7300
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
7301
        $whereConditions = [
7302
            'login_user_id = ? ' => $userId,
7303
        ];
7304
7305
        if (!empty($from) && !empty($until)) {
7306
            $whereConditions["AND (login_date >= '?' "] = $from;
7307
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
7308
        }
7309
7310
        $trackResult = Database::select(
7311
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
7312
            $trackLoginTable,
7313
            [
7314
                'where' => $whereConditions,
7315
            ],
7316
            'first'
7317
        );
7318
7319
        if (false != $trackResult) {
7320
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
7321
        }
7322
7323
        return '00:00:00';
7324
    }
7325
7326
    /**
7327
     * Get the courses list by a course coach.
7328
     *
7329
     * @param int $coachId The coach id
7330
     *
7331
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
7332
     */
7333
    public static function getCoursesListByCourseCoach($coachId)
7334
    {
7335
        $entityManager = Database::getManager();
7336
        $repo = $entityManager->getRepository(SessionRelCourseRelUser::class);
7337
7338
        return $repo->findBy([
7339
            'user' => $coachId,
7340
            'status' => Session::COURSE_COACH,
7341
        ]);
7342
    }
7343
7344
    /**
7345
     * Get the count of user courses in session.
7346
     *
7347
     * @param int $sessionId
7348
     * @param int $courseId
7349
     *
7350
     * @return array
7351
     */
7352
    public static function getTotalUserCoursesInSession($sessionId, $courseId = 0)
7353
    {
7354
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
7355
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7356
7357
        $sessionId = (int) $sessionId;
7358
7359
        if (empty($sessionId)) {
7360
            return [];
7361
        }
7362
7363
        $courseCondition = '';
7364
        if (!empty($courseId)) {
7365
            $courseId = (int) $courseId;
7366
            $courseCondition = "  c_id = $courseId AND ";
7367
        }
7368
7369
        $sql = "SELECT
7370
                    COUNT(u.id) as count,
7371
                    u.id,
7372
                    scu.status status_in_session,
7373
                    u.status user_status
7374
                FROM $table scu
7375
                INNER JOIN $tableUser u
7376
                ON scu.user_id = u.id
7377
                WHERE
7378
                  $courseCondition
7379
                  scu.session_id = ".$sessionId."
7380
                GROUP BY u.id";
7381
7382
        $result = Database::query($sql);
7383
7384
        $list = [];
7385
        while ($data = Database::fetch_assoc($result)) {
7386
            $list[] = $data;
7387
        }
7388
7389
        return $list;
7390
    }
7391
7392
    /**
7393
     * Returns list of a few data from session (name, short description, start
7394
     * date, end date) and the given extra fields if defined based on a
7395
     * session category Id.
7396
     *
7397
     * @param int    $categoryId  The internal ID of the session category
7398
     * @param string $target      Value to search for in the session field values
7399
     * @param array  $extraFields A list of fields to be scanned and returned
7400
     *
7401
     * @return mixed
7402
     */
7403
    public static function getShortSessionListAndExtraByCategory(
7404
        $categoryId,
7405
        $target,
7406
        $extraFields = null,
7407
        $publicationDate = null
7408
    ) {
7409
        $categoryId = (int) $categoryId;
7410
        $sessionList = [];
7411
        // Check if categoryId is valid
7412
        if ($categoryId > 0) {
7413
            $target = Database::escape_string($target);
7414
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7415
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7416
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7417
            // Join session field and session field values tables
7418
            $joinTable = $sfTable.' sf INNER JOIN '.$sfvTable.' sfv ON sf.id = sfv.field_id';
7419
            $fieldsArray = [];
7420
            foreach ($extraFields as $field) {
7421
                $fieldsArray[] = Database::escape_string($field);
7422
            }
7423
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7424
            if (isset($publicationDate)) {
7425
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
7426
                $wherePublication = " AND id NOT IN (
7427
                    SELECT sfv.item_id FROM $joinTable
7428
                    WHERE
7429
                        sf.item_type = $extraFieldType AND
7430
                        ((sf.variable = 'publication_start_date' AND sfv.field_value > '$publicationDateString' and sfv.field_value != '') OR
7431
                        (sf.variable = 'publication_end_date' AND sfv.field_value < '$publicationDateString' and sfv.field_value != ''))
7432
                )";
7433
            }
7434
            // Get the session list from session category and target
7435
            $sessionList = Database::select(
7436
                'id, title, access_start_date, access_end_date',
7437
                $sTable,
7438
                [
7439
                    'where' => [
7440
                        "session_category_id = ? AND id IN (
7441
                            SELECT sfv.item_id FROM $joinTable
7442
                            WHERE
7443
                                sf.item_type = $extraFieldType AND
7444
                                sfv.item_id = session.id AND
7445
                                sf.variable = 'target' AND
7446
                                sfv.field_value = ?
7447
                        ) $wherePublication" => [$categoryId, $target],
7448
                    ],
7449
                ]
7450
            );
7451
            $whereFieldVariables = [];
7452
            $whereFieldIds = [];
7453
            if (
7454
                is_array($fieldsArray) &&
7455
                count($fieldsArray) > 0
7456
            ) {
7457
                $whereParams = '?';
7458
                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...
7459
                    $whereParams .= ', ?';
7460
                }
7461
                $whereFieldVariables = ' variable IN ( '.$whereParams.' )';
7462
                $whereFieldIds = 'field_id IN ( '.$whereParams.' )';
7463
            }
7464
            // Get session fields
7465
            $extraField = new ExtraFieldModel('session');
7466
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
7467
            $fieldsList = $extraField->get_all([
7468
                ' variable IN ( '.$questionMarks.' )' => $fieldsArray,
7469
            ]);
7470
            // Index session fields
7471
            foreach ($fieldsList as $field) {
7472
                $fields[$field['id']] = $field['variable'];
7473
            }
7474
            // Get session field values
7475
            $extra = new ExtraFieldValue('session');
7476
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
7477
            $sessionFieldValueList = $extra->get_all(['where' => ['field_id IN ( '.$questionMarksFields.' )' => array_keys($fields)]]);
7478
            // Add session fields values to session list
7479
            foreach ($sessionList as $id => &$session) {
7480
                foreach ($sessionFieldValueList as $sessionFieldValue) {
7481
                    // Match session field values to session
7482
                    if ($sessionFieldValue['item_id'] == $id) {
7483
                        // Check if session field value is set in session field list
7484
                        if (isset($fields[$sessionFieldValue['field_id']])) {
7485
                            // Avoid overwriting the session's ID field
7486
                            if ('id' != $fields[$sessionFieldValue['field_id']]) {
7487
                                $var = $fields[$sessionFieldValue['field_id']];
7488
                                $val = $sessionFieldValue['value'];
7489
                                // Assign session field value to session
7490
                                $session[$var] = $val;
7491
                            }
7492
                        }
7493
                    }
7494
                }
7495
            }
7496
        }
7497
7498
        return $sessionList;
7499
    }
7500
7501
    /**
7502
     * Return the Session Category id searched by name.
7503
     *
7504
     * @param string $categoryName Name attribute of session category used for search query
7505
     * @param bool   $force        boolean used to get even if something is wrong (e.g not unique name)
7506
     *
7507
     * @return int|array If success, return category id (int), else it will return an array
7508
     *                   with the next structure:
7509
     *                   array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7510
     */
7511
    public static function getSessionCategoryIdByName($categoryName, $force = false)
7512
    {
7513
        // Start error result
7514
        $errorResult = ['error' => true, 'errorMessage' => get_lang('There was an error.')];
7515
        $categoryName = Database::escape_string($categoryName);
7516
        // Check if is not empty category name
7517
        if (!empty($categoryName)) {
7518
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7519
            // Get all session category with same name
7520
            $result = Database::select(
7521
                'id',
7522
                $sessionCategoryTable,
7523
                [
7524
                    'where' => [
7525
                        'title = ?' => $categoryName,
7526
                    ],
7527
                ]
7528
            );
7529
            // Check the result
7530
            if ($result < 1) {
7531
                // If not found any result, update error message
7532
                $errorResult['errorMessage'] = 'Not found any session category name '.$categoryName;
7533
            } elseif (count($result) > 1 && !$force) {
7534
                // If found more than one result and force is disabled, update error message
7535
                $errorResult['errorMessage'] = 'Found many session categories';
7536
            } elseif (1 == count($result) || $force) {
7537
                // If found just one session category or force option is enabled
7538
7539
                return key($result);
7540
            }
7541
        } else {
7542
            // category name is empty, update error message
7543
            $errorResult['errorMessage'] = 'Not valid category name';
7544
        }
7545
7546
        return $errorResult;
7547
    }
7548
7549
    /**
7550
     * Return all data from sessions (plus extra field, course and coach data) by category id.
7551
     *
7552
     * @param int $sessionCategoryId session category id used to search sessions
7553
     *
7554
     * @return array If success, return session list and more session related data, else it will return an array
7555
     *               with the next structure:
7556
     *               array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7557
     */
7558
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
7559
    {
7560
        // Start error result
7561
        $errorResult = [
7562
            'error' => true,
7563
            'errorMessage' => get_lang('There was an error.'),
7564
        ];
7565
7566
        $sessionCategoryId = intval($sessionCategoryId);
7567
        // Check if session category id is valid
7568
        if ($sessionCategoryId > 0) {
7569
            // Get table names
7570
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7571
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7572
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7573
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7574
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
7575
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7576
7577
            // Get all data from all sessions whit the session category specified
7578
            $sessionList = Database::select(
7579
                '*',
7580
                $sessionTable,
7581
                [
7582
                    'where' => [
7583
                        'session_category_id = ?' => $sessionCategoryId,
7584
                    ],
7585
                ]
7586
            );
7587
7588
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7589
7590
            // Check if session list query had result
7591
            if (!empty($sessionList)) {
7592
                // implode all session id
7593
                $sessionIdsString = '('.implode(', ', array_keys($sessionList)).')';
7594
                // Get all field variables
7595
                $sessionFieldList = Database::select(
7596
                    'id, variable',
7597
                    $sessionFieldTable,
7598
                    ['item_type = ? ' => [$extraFieldType]]
7599
                );
7600
7601
                // Get all field values
7602
                $sql = "SELECT item_id, field_id, value FROM
7603
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
7604
                        ON (f.id = v.field_id)
7605
                        WHERE
7606
                            item_id IN $sessionIdsString AND
7607
                            item_type = $extraFieldType
7608
                ";
7609
                $result = Database::query($sql);
7610
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
7611
7612
                // Check if session field values had result
7613
                if (!empty($sessionFieldValueList)) {
7614
                    $sessionFieldValueListBySession = [];
7615
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
7616
                        // Create an array to index ids to session id
7617
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
7618
                    }
7619
                }
7620
                // Query used to find course-coaches from sessions
7621
                $sql = "SELECT
7622
                            scu.session_id,
7623
                            c.id AS course_id,
7624
                            c.code AS course_code,
7625
                            c.title AS course_title,
7626
                            u.username AS coach_username,
7627
                            u.firstname AS coach_firstname,
7628
                            u.lastname AS coach_lastname
7629
                        FROM $courseTable c
7630
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
7631
                        INNER JOIN $userTable u ON scu.user_id = u.id
7632
                        WHERE scu.status = ".Session::COURSE_COACH." AND scu.session_id IN $sessionIdsString
7633
                        ORDER BY scu.session_id ASC ";
7634
                $res = Database::query($sql);
7635
                $sessionCourseList = Database::store_result($res, 'ASSOC');
7636
                // Check if course list had result
7637
                if (!empty($sessionCourseList)) {
7638
                    foreach ($sessionCourseList as $key => $sessionCourse) {
7639
                        // Create an array to index ids to session_id
7640
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
7641
                    }
7642
                }
7643
                // Join lists
7644
                if (is_array($sessionList)) {
7645
                    foreach ($sessionList as $id => &$row) {
7646
                        if (
7647
                            !empty($sessionFieldValueListBySession) &&
7648
                            is_array($sessionFieldValueListBySession[$id])
7649
                        ) {
7650
                            // If have an index array for session extra fields, use it to join arrays
7651
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
7652
                                $row['extra'][$key] = [
7653
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
7654
                                    'value' => $sessionFieldValueList[$key]['value'],
7655
                                ];
7656
                            }
7657
                        }
7658
                        if (
7659
                            !empty($sessionCourseListBySession) &&
7660
                            is_array($sessionCourseListBySession[$id])
7661
                        ) {
7662
                            // If have an index array for session course coach, use it to join arrays
7663
                            foreach ($sessionCourseListBySession[$id] as $key) {
7664
                                $row['course'][$key] = [
7665
                                    'course_id' => $sessionCourseList[$key]['course_id'],
7666
                                    'course_code' => $sessionCourseList[$key]['course_code'],
7667
                                    'course_title' => $sessionCourseList[$key]['course_title'],
7668
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
7669
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
7670
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
7671
                                ];
7672
                            }
7673
                        }
7674
                    }
7675
                }
7676
7677
                return $sessionList;
7678
            } else {
7679
                // Not found result, update error message
7680
                $errorResult['errorMessage'] = 'Not found any session for session category id '.$sessionCategoryId;
7681
            }
7682
        }
7683
7684
        return $errorResult;
7685
    }
7686
7687
    /**
7688
     * Return session description from session id.
7689
     *
7690
     * @param int $sessionId
7691
     *
7692
     * @return string
7693
     */
7694
    public static function getDescriptionFromSessionId($sessionId)
7695
    {
7696
        // Init variables
7697
        $sessionId = (int) $sessionId;
7698
        $description = '';
7699
        // Check if session id is valid
7700
        if ($sessionId > 0) {
7701
            // Select query from session id
7702
            $rows = Database::select(
7703
                'description',
7704
                Database::get_main_table(TABLE_MAIN_SESSION),
7705
                [
7706
                    'where' => [
7707
                        'id = ?' => $sessionId,
7708
                    ],
7709
                ]
7710
            );
7711
7712
            // Check if select query result is not empty
7713
            if (!empty($rows)) {
7714
                // Get session description
7715
                $description = $rows[0]['description'];
7716
            }
7717
        }
7718
7719
        return $description;
7720
    }
7721
7722
    /**
7723
     * Get a session list filtered by name, description or any of the given extra fields.
7724
     *
7725
     * @param string $term                 The term to search
7726
     * @param array  $extraFieldsToInclude Extra fields to include in the session data
7727
     *
7728
     * @return array The list
7729
     */
7730
    public static function searchSession($term, $extraFieldsToInclude = [])
7731
    {
7732
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7733
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7734
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7735
        $term = Database::escape_string($term);
7736
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7737
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
7738
            $resultData = Database::select('*', $sTable, [
7739
                'where' => [
7740
                    "title LIKE %?% " => $term,
7741
                    " OR description LIKE %?% " => $term,
7742
                    " OR id IN (
7743
                    SELECT item_id
7744
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
7745
                    ON (v.field_id = e.id)
7746
                    WHERE field_value LIKE %?% AND item_type = $extraFieldType
7747
                ) " => $term,
7748
                ],
7749
            ]);
7750
        } else {
7751
            $resultData = Database::select('*', $sTable, [
7752
                'where' => [
7753
                    "title LIKE %?% " => $term,
7754
                    "OR description LIKE %?% " => $term,
7755
                ],
7756
            ]);
7757
7758
            return $resultData;
7759
        }
7760
7761
        foreach ($resultData as $id => &$session) {
7762
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
7763
        }
7764
7765
        return $resultData;
7766
    }
7767
7768
    /**
7769
     * @param int   $sessionId
7770
     * @param array $extraFieldsToInclude (empty means all)
7771
     *
7772
     * @return array
7773
     */
7774
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = [])
7775
    {
7776
        $extraData = [];
7777
        $variables = [];
7778
        $variablePlaceHolders = [];
7779
7780
        foreach ($extraFieldsToInclude as $sessionExtraField) {
7781
            $variablePlaceHolders[] = "?";
7782
            $variables[] = Database::escape_string($sessionExtraField);
7783
        }
7784
7785
        $sessionExtraField = new ExtraFieldModel('session');
7786
        $fieldList = $sessionExtraField->get_all(empty($extraFieldsToInclude) ? [] : [
7787
            "variable IN ( ".implode(", ", $variablePlaceHolders)." ) " => $variables,
7788
        ]);
7789
7790
        if (empty($fieldList)) {
7791
            return [];
7792
        }
7793
7794
        $fields = [];
7795
7796
        // Index session fields
7797
        foreach ($fieldList as $field) {
7798
            $fields[$field['id']] = $field['variable'];
7799
        }
7800
7801
        // Get session field values
7802
        $extra = new ExtraFieldValue('session');
7803
        $sessionFieldValueList = [];
7804
        foreach (array_keys($fields) as $fieldId) {
7805
            $sessionFieldValue = $extra->get_values_by_handler_and_field_id($sessionId, $fieldId);
7806
            if (false != $sessionFieldValue) {
7807
                $sessionFieldValueList[$fieldId] = $sessionFieldValue;
7808
            }
7809
        }
7810
7811
        foreach ($sessionFieldValueList as $sessionFieldValue) {
7812
            // Match session field values to session
7813
            if ($sessionFieldValue['item_id'] != $sessionId) {
7814
                continue;
7815
            }
7816
7817
            // Check if session field value is set in session field list
7818
            if (!isset($fields[$sessionFieldValue['field_id']])) {
7819
                continue;
7820
            }
7821
7822
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
7823
            $extrafieldValue = $sessionFieldValue['value'];
7824
7825
            $extraData[] = [
7826
                'variable' => $extrafieldVariable,
7827
                'value' => $extrafieldValue,
7828
            ];
7829
        }
7830
7831
        return $extraData;
7832
    }
7833
7834
    /**
7835
     * @param int $sessionId
7836
     *
7837
     * @return bool
7838
     */
7839
    public static function isValidId($sessionId)
7840
    {
7841
        $sessionId = (int) $sessionId;
7842
        if ($sessionId > 0) {
7843
            $rows = Database::select(
7844
                'id',
7845
                Database::get_main_table(TABLE_MAIN_SESSION),
7846
                ['where' => ['id = ?' => $sessionId]]
7847
            );
7848
            if (!empty($rows)) {
7849
                return true;
7850
            }
7851
        }
7852
7853
        return false;
7854
    }
7855
7856
    /**
7857
     * Get list of sessions based on users of a group for a group admin.
7858
     *
7859
     * @param int $userId The user id
7860
     *
7861
     * @return array
7862
     */
7863
    public static function getSessionsFollowedForGroupAdmin($userId)
7864
    {
7865
        $sessionList = [];
7866
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7867
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7868
        $userGroup = new UserGroupModel();
7869
        $userIdList = $userGroup->getGroupUsersByUser($userId);
7870
7871
        if (empty($userIdList)) {
7872
            return [];
7873
        }
7874
7875
        $sql = "SELECT DISTINCT s.*
7876
                FROM $sessionTable s
7877
                INNER JOIN $sessionUserTable sru
7878
                ON s.id = sru.id_session
7879
                WHERE
7880
                    (sru.id_user IN (".implode(', ', $userIdList).")
7881
                    AND sru.relation_type = ".Session::STUDENT."
7882
                )";
7883
7884
        if (api_is_multiple_url_enabled()) {
7885
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7886
            $accessUrlId = api_get_current_access_url_id();
7887
7888
            if (-1 != $accessUrlId) {
7889
                $sql = "SELECT DISTINCT s.*
7890
                        FROM $sessionTable s
7891
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
7892
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
7893
                        WHERE
7894
                            srau.access_url_id = $accessUrlId
7895
                            AND (
7896
                                sru.id_user IN (".implode(', ', $userIdList).")
7897
                                AND sru.relation_type = ".Session::STUDENT."
7898
                            )";
7899
            }
7900
        }
7901
7902
        $result = Database::query($sql);
7903
        while ($row = Database::fetch_assoc($result)) {
7904
            $sessionList[] = $row;
7905
        }
7906
7907
        return $sessionList;
7908
    }
7909
7910
    public static function getSessionVisibility(Session $session) : string
7911
    {
7912
        switch ($session->getVisibility()) {
7913
            case 1:
7914
                return get_lang('Read only');
7915
            case 2:
7916
                return get_lang('Visible');
7917
            case 3:
7918
                return api_ucfirst(get_lang('invisible'));
7919
        }
7920
7921
        return '';
7922
    }
7923
7924
    /**
7925
     * Returns a human readable string.
7926
     *
7927
     * @return array
7928
     */
7929
    public static function parseSessionDates(Session $session, bool $showTime = false)
7930
    {
7931
        $displayDates = self::convertSessionDateToString(
7932
            $session->getDisplayStartDate(),
7933
            $session->getDisplayEndDate(),
7934
            $showTime,
7935
            true
7936
        );
7937
        $accessDates = self::convertSessionDateToString(
7938
            $session->getAccessStartDate(),
7939
            $session->getAccessEndDate(),
7940
            $showTime,
7941
            true
7942
        );
7943
7944
        $coachDates = self::convertSessionDateToString(
7945
            $session->getCoachAccessStartDate(),
7946
            $session->getCoachAccessEndDate(),
7947
            $showTime,
7948
            true
7949
        );
7950
7951
        return [
7952
            'access' => $accessDates,
7953
            'display' => $displayDates,
7954
            'coach' => $coachDates,
7955
        ];
7956
    }
7957
7958
    /**
7959
     * @throws Exception
7960
     */
7961
    public static function setForm(FormValidator $form, Session $session = null, $fromSessionId = null): array
7962
    {
7963
        $categoriesList = self::get_all_session_category();
7964
7965
        $categoriesOptions = [
7966
            '0' => get_lang('none'),
7967
        ];
7968
7969
        if (false != $categoriesList) {
7970
            foreach ($categoriesList as $categoryItem) {
7971
                $categoriesOptions[$categoryItem['id']] = $categoryItem['title'];
7972
            }
7973
        }
7974
7975
        // Database Table Definitions
7976
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7977
7978
        $form->addText(
7979
            'title',
7980
            get_lang('Session name'),
7981
            true,
7982
            ['maxlength' => 150, 'aria-label' => get_lang('Session name')]
7983
        );
7984
        $form->addRule('title', get_lang('Session name already exists'), 'callback', 'check_session_name');
7985
7986
        if (!api_is_platform_admin() && api_is_teacher()) {
7987
            $form->addSelectFromCollection(
7988
                'coach_username',
7989
                get_lang('Coach name'),
7990
                [api_get_user_entity()],
7991
                [
7992
                    'id' => 'coach_username',
7993
                    'style' => 'width:370px;',
7994
                    'multiple' => true,
7995
                ],
7996
                false,
7997
                'getFullname'
7998
            );
7999
        } else {
8000
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE active <> ".USER_SOFT_DELETED." AND status = 1";
8001
            $rs = Database::query($sql);
8002
            $countUsers = (int) Database::result($rs, 0, '0');
8003
8004
            if ($countUsers < 1) {
8005
                $orderClause = 'ORDER BY ';
8006
                $orderClause .= api_sort_by_first_name() ? 'firstname, lastname, username' : 'lastname, firstname, username';
8007
8008
                $sql = "SELECT id as user_id, lastname, firstname, username
8009
                        FROM $tbl_user
8010
                        WHERE active <> -1 AND status = '1' ".
8011
                        $orderClause;
8012
8013
                if (api_is_multiple_url_enabled()) {
8014
                    $userRelAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
8015
                    $accessUrlId = api_get_current_access_url_id();
8016
                    if (-1 != $accessUrlId) {
8017
                        $sql = "SELECT user.id as user_id, username, lastname, firstname
8018
                        FROM $tbl_user user
8019
                        INNER JOIN $userRelAccessUrlTable url_user
8020
                        ON (url_user.user_id = user.id)
8021
                        WHERE
8022
                            user.active <> -1 AND
8023
                            access_url_id = $accessUrlId AND
8024
                            status = 1 "
8025
                            .$orderClause;
8026
                    }
8027
                }
8028
8029
                $result = Database::query($sql);
8030
                $coachesList = Database::store_result($result);
8031
                $coachesOptions = [];
8032
                foreach ($coachesList as $coachItem) {
8033
                    $coachesOptions[$coachItem['user_id']] =
8034
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
8035
                }
8036
8037
                $form->addSelect(
8038
                    'coach_username',
8039
                    get_lang('Coach name'),
8040
                    $coachesOptions,
8041
                    [
8042
                        'id' => 'coach_username',
8043
                        'style' => 'width:370px;',
8044
                        'multiple' => true,
8045
                    ]
8046
                );
8047
            } else {
8048
                $coaches = [];
8049
8050
                if ($session) {
8051
                    foreach ($session->getGeneralCoaches() as $coach) {
8052
                        $coaches[$coach->getId()] = $coach->getFullName();
8053
                    }
8054
                }
8055
8056
                $form->addSelectAjax(
8057
                    'coach_username',
8058
                    get_lang('Coach name'),
8059
                    $coaches,
8060
                    [
8061
                        'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_general_coach',
8062
                        'width' => '100%',
8063
                        'id' => 'coach_username',
8064
                        'multiple' => true,
8065
                    ]
8066
                );
8067
            }
8068
        }
8069
8070
        $form->addRule('coach_username', get_lang('Required field'), 'required');
8071
        $form->addHtml('<div id="ajax_list_coachs"></div>');
8072
8073
        $form->addButtonAdvancedSettings('advanced_params');
8074
        $form->addElement('html', '<div id="advanced_params_options" style="'.(isset($fromSessionId) ? 'display:block' : 'display:none').'">');
8075
8076
        if (null === $session) {
8077
            $form->addSelectAjax(
8078
                'session_template',
8079
                get_lang('Session template'),
8080
                [],
8081
                [
8082
                    'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_template_session',
8083
                    'id' => 'system_template',
8084
                ]
8085
            );
8086
        }
8087
8088
        if (isset($fromSessionId)) {
8089
            $session = api_get_session_entity($fromSessionId);
8090
        }
8091
        $form->addSelect(
8092
            'session_category',
8093
            get_lang('Sessions categories'),
8094
            $categoriesOptions,
8095
            [
8096
                'id' => 'session_category',
8097
            ]
8098
        );
8099
8100
        $statusList = self::getStatusList();
8101
        $form->addSelect(
8102
            'status',
8103
            get_lang('Session status'),
8104
            $statusList,
8105
            [
8106
                'id' => 'status',
8107
            ]
8108
        );
8109
8110
        $form->addHtmlEditor(
8111
            'description',
8112
            get_lang('Description'),
8113
            false,
8114
            false,
8115
            [
8116
                'ToolbarSet' => 'Minimal',
8117
            ]
8118
        );
8119
8120
        $form->addElement('checkbox', 'show_description', null, get_lang('Show description'));
8121
8122
        $visibilityGroup = [];
8123
        $visibilityGroup[] = $form->createElement(
8124
            'select',
8125
            'session_visibility',
8126
            null,
8127
            [
8128
                SESSION_VISIBLE_READ_ONLY => get_lang('Read only'),
8129
                SESSION_VISIBLE => get_lang('Accessible'),
8130
                SESSION_INVISIBLE => api_ucfirst(get_lang('Not accessible')),
8131
            ],
8132
            []
8133
        );
8134
        $form->addGroup(
8135
            $visibilityGroup,
8136
            'visibility_group',
8137
            get_lang('Visibility after end date'),
8138
            null,
8139
            false
8140
        );
8141
8142
        $options = [
8143
            0 => get_lang('By duration'),
8144
            1 => get_lang('By dates'),
8145
        ];
8146
8147
        $form->addSelect('access', get_lang('Access'), $options, [
8148
            'onchange' => 'accessSwitcher(this.value)',
8149
            'id' => 'access',
8150
        ]);
8151
8152
        $form->addHtml('<div id="duration_div" style="display:none">');
8153
        $form->addElement(
8154
            'number',
8155
            'duration',
8156
            [
8157
                get_lang('Session duration'),
8158
                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.'),
8159
            ],
8160
            [
8161
                'maxlength' => 50,
8162
            ]
8163
        );
8164
8165
        $form->addHtml('</div>');
8166
        $form->addHtml('<div id="date_fields" style="display:none">');
8167
8168
        // Dates
8169
        $form->addDateTimePicker(
8170
            'access_start_date',
8171
            [get_lang('Access start date'), get_lang('Date on which the session is made available to all')],
8172
            ['id' => 'access_start_date']
8173
        );
8174
8175
        $form->addDateTimePicker(
8176
            'access_end_date',
8177
            [get_lang('Access end date'), get_lang('Date on which the session is closed')],
8178
            ['id' => 'access_end_date']
8179
        );
8180
8181
        $form->addRule(
8182
            ['access_start_date', 'access_end_date'],
8183
            get_lang('Start date must be before the end date'),
8184
            'compare_datetime_text',
8185
            '< allow_empty'
8186
        );
8187
8188
        $form->addDateTimePicker(
8189
            'display_start_date',
8190
            [
8191
                get_lang('Start date to display'),
8192
                get_lang('Date that will be shown in the session information as the date on which the session starts'),
8193
            ],
8194
            ['id' => 'display_start_date']
8195
        );
8196
8197
        $form->addDateTimePicker(
8198
            'display_end_date',
8199
            [
8200
                get_lang('End date to display'),
8201
                get_lang('Date that will be shown in the session information as the date on which the session ends'),
8202
            ],
8203
            ['id' => 'display_end_date']
8204
        );
8205
8206
        $form->addRule(
8207
            ['display_start_date', 'display_end_date'],
8208
            get_lang('Start date must be before the end date'),
8209
            'compare_datetime_text',
8210
            '< allow_empty'
8211
        );
8212
8213
        $form->addDateTimePicker(
8214
            'coach_access_start_date',
8215
            [
8216
                get_lang('Access start date for coaches'),
8217
                get_lang('Date on which the session is made available to coaches, so they can prepare it before the students get connected'),
8218
            ],
8219
            ['id' => 'coach_access_start_date']
8220
        );
8221
8222
        $form->addDateTimePicker(
8223
            'coach_access_end_date',
8224
            [
8225
                get_lang('Access end date for coaches'),
8226
                get_lang('Date on which the session is closed to coaches. The additional delay will allow them to export all relevant tracking information'),
8227
            ],
8228
            ['id' => 'coach_access_end_date']
8229
        );
8230
8231
        $form->addRule(
8232
            ['coach_access_start_date', 'coach_access_end_date'],
8233
            get_lang('Start date must be before the end date'),
8234
            'compare_datetime_text',
8235
            '< allow_empty'
8236
        );
8237
8238
        $form->addElement('html', '</div>');
8239
8240
        $form->addCheckBox(
8241
            'send_subscription_notification',
8242
            get_lang('Send an email when a user being subscribed to session'),
8243
        );
8244
8245
        $form->addCheckBox(
8246
            'notify_boss',
8247
            get_lang('Notify inscription of user to student boss')
8248
        );
8249
8250
        // Picture
8251
        $form->addFile(
8252
            'picture',
8253
            get_lang('Add image'),
8254
            ['id' => 'picture', 'class' => 'picture-form', 'crop_image' => true]
8255
        );
8256
        $allowedPictureTypes = api_get_supported_image_extensions(false);
8257
        $form->addRule('picture', get_lang('Only PNG, JPG or GIF images allowed').' ('.implode(',', $allowedPictureTypes).')', 'filetype', $allowedPictureTypes);
8258
8259
        if ($session && $session->getImage()) {
8260
            if (isset($fromSessionId)) {
8261
                $imageUrl = self::getSessionPictureUrl($session);
8262
                $form->addLabel(get_lang('Image'), "<img src = '$imageUrl' />");
8263
                $form->addHidden('image_session_template', $imageUrl);
8264
8265
            } else {
8266
                $form->addElement('checkbox', 'delete_picture', null, get_lang('Delete picture'));
8267
                $imageUrl = self::getSessionPictureUrl($session);
8268
                $form->addLabel(get_lang('Image'), "<img src = '$imageUrl' />");
8269
            }
8270
        }
8271
8272
        // Extra fields
8273
        $extra_field = new ExtraFieldModel('session');
8274
        $extra = $extra_field->addElements($form, $session ? $session->getId() : 0, ['image']);
8275
8276
        $form->addElement('html', '</div>');
8277
8278
        $js = $extra['jquery_ready_content'];
8279
8280
        return ['js' => $js];
8281
    }
8282
8283
    /**
8284
     * Saves the session picture.
8285
     *
8286
     * @param int    $sessionId
8287
     * @param array  $file
8288
     * @param string $crop
8289
     *
8290
     * @return false
8291
     */
8292
    public static function updateSessionPicture(
8293
        $sessionId,
8294
        $file,
8295
        string $crop = ''
8296
    ) {
8297
        if (empty($file)) {
8298
            return false;
8299
        }
8300
8301
        $sessionRepo = Container::getSessionRepository();
8302
        $assetRepo = Container::getAssetRepository();
8303
8304
        $asset = (new Asset())
8305
            ->setCategory(Asset::SESSION)
8306
            ->setTitle($file['name'])
8307
        ;
8308
        if (!empty($crop)) {
8309
            $asset->setCrop($crop);
8310
        }
8311
        $asset = $assetRepo->createFromRequest($asset, $file);
8312
8313
        /** @var Session $session */
8314
        $session = $sessionRepo->find($sessionId);
8315
        $session->setImage($asset);
8316
        $sessionRepo->update($session);
8317
    }
8318
8319
    /**
8320
     * Deletes de session picture as asset.
8321
     *
8322
     * @param int $sessionId
8323
     */
8324
    public static function deleteAsset(int $sessionId): void
8325
    {
8326
        $sessionRepo = Container::getSessionRepository();
8327
8328
        /** @var Session $session */
8329
        $session = $sessionRepo->find($sessionId);
8330
        $em = Database::getManager();
8331
        if ($session->hasImage()) {
8332
            $asset = $session->getImage();
8333
            $em->remove($asset);
8334
            $em->flush();
8335
        }
8336
    }
8337
8338
    /**
8339
     * Get the session picture url.
8340
     *
8341
     * @param Session $session
8342
     * @return string
8343
     */
8344
    public static function getSessionPictureUrl(Session $session): string
8345
    {
8346
        $assetRepo = Container::getAssetRepository();
8347
        $imageUrl = $assetRepo->getAssetUrl($session->getImage());
8348
8349
        return $imageUrl;
8350
    }
8351
8352
    /**
8353
     * Gets the number of rows in the session table filtered through the given
8354
     * array of parameters.
8355
     *
8356
     * @param array Array of options/filters/keys
8357
     *
8358
     * @return int The number of rows, or false on wrong param
8359
     * @assert ('a') === false
8360
     */
8361
    public static function get_count_admin_complete($options = [])
8362
    {
8363
        if (!is_array($options)) {
8364
            return false;
8365
        }
8366
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8367
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8368
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8369
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8370
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
8371
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8372
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8373
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
8374
8375
        $where = 'WHERE 1 = 1 AND u.active <> -1 ';
8376
8377
        if (api_is_session_admin() &&
8378
            'false' == api_get_setting('allow_session_admins_to_see_all_sessions')
8379
        ) {
8380
            $user_id = api_get_user_id();
8381
            $where .= ' AND (sru.relation_type = '.Session::SESSION_ADMIN." AND sru.user_id = $user_id) ";
8382
        } else {
8383
            $where .= ' AND sru.relation_type = '.Session::GENERAL_COACH.' ';
8384
        }
8385
8386
        $extraFieldTables = '';
8387
        if (!empty($options['where'])) {
8388
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8389
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8390
8391
            $options['where'] = str_replace(
8392
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8393
                [') GROUP BY s.title HAVING session_active = 1 ', " GROUP BY s.title HAVING session_active = 1 "],
8394
                $options['where']
8395
            );
8396
8397
            $options['where'] = str_replace(
8398
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8399
                [') GROUP BY s.title HAVING session_active = 0 ', " GROUP BY s.title HAVING session_active = '0' "],
8400
                $options['where']
8401
            );
8402
8403
            if (!empty($options['extra'])) {
8404
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8405
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8406
8407
                foreach ($options['extra'] as $extra) {
8408
                    $options['where'] = str_replace(
8409
                        $extra['field'],
8410
                        'fv.field_id = '.$extra['id'].' AND fvo.option_value',
8411
                        $options['where']
8412
                    );
8413
                    $extraFieldTables = "$tbl_session_field_values fv, $tbl_session_field_options fvo, ";
8414
                }
8415
            }
8416
            $where .= ' AND '.$options['where'];
8417
        }
8418
8419
        $today = api_get_utc_datetime();
8420
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.title,
8421
                        IF (
8422
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8423
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8424
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8425
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8426
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8427
                        , 1, 0) as session_active
8428
                       FROM $extraFieldTables $tbl_session s
8429
                       LEFT JOIN  $tbl_session_category sc
8430
                       ON s.session_category_id = sc.id
8431
                       INNER JOIN $tblSessionRelUser sru
8432
                       ON s.id = sru.session_id
8433
                       INNER JOIN $tbl_user u
8434
                       ON sru.user_id = u.id
8435
                       INNER JOIN $sessionCourseUserTable scu
8436
                       ON s.id = scu.session_id
8437
                       INNER JOIN $courseTable c
8438
                       ON c.id = scu.c_id
8439
                       $where ";
8440
8441
        if (api_is_multiple_url_enabled()) {
8442
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8443
            $access_url_id = api_get_current_access_url_id();
8444
            if (-1 != $access_url_id) {
8445
                $where .= " AND ar.access_url_id = $access_url_id ";
8446
                $query_rows = "SELECT count(*) as total_rows
8447
                               FROM $tbl_session s
8448
                               LEFT JOIN  $tbl_session_category sc
8449
                               ON s.session_category_id = sc.id
8450
                               INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
8451
                               INNER JOIN $tbl_user u
8452
                               ON sru.user_id = u.id
8453
                               INNER JOIN $table_access_url_rel_session ar
8454
                               ON ar.session_id = s.id $where ";
8455
            }
8456
        }
8457
8458
        $result = Database::query($query_rows);
8459
        $num = 0;
8460
        if (Database::num_rows($result)) {
8461
            $rows = Database::fetch_array($result);
8462
            $num = $rows['total_rows'];
8463
        }
8464
8465
        return $num;
8466
    }
8467
8468
    /**
8469
     * @param string $listType
8470
     * @param array  $extraFields
8471
     *
8472
     * @return array
8473
     */
8474
    public static function getGridColumns(
8475
        $listType = 'all',
8476
        $extraFields = [],
8477
        $addExtraFields = true
8478
    ) {
8479
        $showCount = ('true' === api_get_setting('session.session_list_show_count_users'));
8480
        // Column config
8481
        $operators = ['cn', 'nc'];
8482
        $date_operators = ['gt', 'ge', 'lt', 'le'];
8483
8484
        switch ($listType) {
8485
            case 'my_space':
8486
                $columns = [
8487
                    get_lang('Title'),
8488
                    get_lang('Date'),
8489
                    get_lang('Number of courses per session'),
8490
                    get_lang('Number of learners by session'),
8491
                    get_lang('Details'),
8492
                ];
8493
8494
                $columnModel = [
8495
                    ['name' => 'title', 'index' => 'title', 'align' => 'left'],
8496
                    ['name' => 'date', 'index' => 'access_start_date', 'align' => 'left'],
8497
                    [
8498
                        'name' => 'course_per_session',
8499
                        'index' => 'course_per_session',
8500
                        'sortable' => 'false',
8501
                        'search' => 'false',
8502
                    ],
8503
                    [
8504
                        'name' => 'student_per_session',
8505
                        'index' => 'student_per_session',
8506
                        'sortable' => 'false',
8507
                        'search' => 'false',
8508
                    ],
8509
                    [
8510
                        'name' => 'actions',
8511
                        'index' => 'actions',
8512
                        'sortable' => 'false',
8513
                        'search' => 'false',
8514
                    ],
8515
                ];
8516
                break;
8517
            case 'all':
8518
            case 'active':
8519
            case 'close':
8520
                $columns = [
8521
                    '#',
8522
                    get_lang('Title'),
8523
                    get_lang('Category'),
8524
                    get_lang('Start date to display'),
8525
                    get_lang('End date to display'),
8526
                    get_lang('Visibility'),
8527
                ];
8528
8529
                $columnModel = [
8530
                    [
8531
                        'name' => 'id',
8532
                        'index' => 's.id',
8533
                        'hidden' => 'true',
8534
                    ],
8535
                    [
8536
                        'name' => 'title',
8537
                        'index' => 's.title',
8538
                        'width' => '160',
8539
                        'align' => 'left',
8540
                        'search' => 'true',
8541
                        'searchoptions' => ['sopt' => $operators],
8542
                    ],
8543
                    [
8544
                        'name' => 'category_name',
8545
                        'index' => 'category_name',
8546
                        'align' => 'left',
8547
                        'search' => 'true',
8548
                        'searchoptions' => ['sopt' => $operators],
8549
                    ],
8550
                    [
8551
                        'name' => 'display_start_date',
8552
                        'index' => 'display_start_date',
8553
                        'align' => 'left',
8554
                        'search' => 'true',
8555
                        'searchoptions' => [
8556
                            'dataInit' => 'date_pick_today',
8557
                            'sopt' => $date_operators,
8558
                        ],
8559
                    ],
8560
                    [
8561
                        'name' => 'display_end_date',
8562
                        'index' => 'display_end_date',
8563
                        'align' => 'left',
8564
                        'search' => 'true',
8565
                        'searchoptions' => [
8566
                            'dataInit' => 'date_pick_one_month',
8567
                            'sopt' => $date_operators,
8568
                        ],
8569
                    ],
8570
                    [
8571
                        'name' => 'visibility',
8572
                        'index' => 'visibility',
8573
                        'align' => 'left',
8574
                        'search' => 'false',
8575
                    ],
8576
                ];
8577
8578
                if ($showCount) {
8579
                    $columns[] = get_lang('Users');
8580
                    $columnModel[] = [
8581
                        'name' => 'users',
8582
                        'index' => 'users',
8583
                        'align' => 'left',
8584
                        'search' => 'false',
8585
                    ];
8586
8587
                    // ofaj
8588
                    $columns[] = get_lang('Teachers');
8589
                    $columnModel[] = [
8590
                        'name' => 'teachers',
8591
                        'index' => 'teachers',
8592
                        'align' => 'left',
8593
                        'search' => 'false',
8594
                    ];
8595
                }
8596
8597
                $columns[] = get_lang('Session status');
8598
                $list = self::getStatusList();
8599
                $listToString = '';
8600
                foreach ($list as $statusId => $status) {
8601
                    $listToString .= $statusId.':'.$status.';';
8602
                }
8603
8604
                $columnModel[] = [
8605
                    'name' => 'status',
8606
                    'index' => 'status',
8607
                    'align' => 'left',
8608
                    'search' => 'true',
8609
                    'stype' => 'select',
8610
                    // for the bottom bar
8611
                    'searchoptions' => [
8612
                        'defaultValue' => '1',
8613
                        'value' => $listToString,
8614
                    ],
8615
                ];
8616
8617
                break;
8618
8619
            case 'simple':
8620
                $columns = [
8621
                    '#',
8622
                    get_lang('Title'),
8623
                    get_lang('Category'),
8624
                    get_lang('Session Display Start Date'),
8625
                    get_lang('Session Display End Date'),
8626
                    get_lang('Visibility'),
8627
                ];
8628
8629
                $columnModel = [
8630
                    [
8631
                        'name' => 'id',
8632
                        'index' => 's.id',
8633
                        'hidden' => 'true',
8634
                    ],
8635
                    [
8636
                        'name' => 'title',
8637
                        'index' => 's.title',
8638
                        'width' => '160',
8639
                        'align' => 'left',
8640
                        'search' => 'true',
8641
                        'searchoptions' => ['sopt' => $operators],
8642
                    ],
8643
                    [
8644
                        'name' => 'category_name',
8645
                        'index' => 'category_name',
8646
                        'align' => 'left',
8647
                        'search' => 'true',
8648
                        'searchoptions' => ['sopt' => $operators],
8649
                    ],
8650
                    [
8651
                        'name' => 'display_start_date',
8652
                        'index' => 'display_start_date',
8653
                        'align' => 'left',
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
                        'search' => 'true',
8665
                        'searchoptions' => [
8666
                            'dataInit' => 'date_pick_one_month',
8667
                            'sopt' => $date_operators,
8668
                        ],
8669
                    ],
8670
                    [
8671
                        'name' => 'visibility',
8672
                        'index' => 'visibility',
8673
                        'align' => 'left',
8674
                        'search' => 'false',
8675
                    ],
8676
                ];
8677
8678
                if ($showCount) {
8679
                    $columns[] = get_lang('Users');
8680
                    $columnModel[] = [
8681
                        'name' => 'users',
8682
                        'index' => 'users',
8683
                        'align' => 'left',
8684
                        'search' => 'false',
8685
                    ];
8686
8687
                    // ofaj
8688
                    $columns[] = get_lang('Teachers');
8689
                    $columnModel[] = [
8690
                        'name' => 'teachers',
8691
                        'index' => 'teachers',
8692
                        'align' => 'left',
8693
                        'search' => 'false',
8694
                    ];
8695
                }
8696
8697
                $columns[] = get_lang('Session status');
8698
                $list = self::getStatusList();
8699
                $listToString = '';
8700
                foreach ($list as $statusId => $status) {
8701
                    $listToString .= $statusId.':'.$status.';';
8702
                }
8703
8704
                $columnModel[] = ['name' => 'status', 'index' => 'status', 'align' => 'left', 'search' => 'true', 'stype' => 'select',
8705
                    // for the bottom bar
8706
                    'searchoptions' => [
8707
                        'defaultValue' => '1',
8708
                        'value' => $listToString,
8709
                    ],
8710
                ];
8711
8712
                break;
8713
            case 'complete':
8714
                $columns = [
8715
                    get_lang('Title'),
8716
                    get_lang('Start date to display'),
8717
                    get_lang('End date to display'),
8718
                    get_lang('Coach'),
8719
                    get_lang('Status'),
8720
                    get_lang('Visibility'),
8721
                    get_lang('Course title'),
8722
                ];
8723
                $columnModel = [
8724
                    [
8725
                        'name' => 'title',
8726
                        'index' => 's.title',
8727
                        'width' => '200',
8728
                        'align' => 'left',
8729
                        'search' => 'true',
8730
                        'searchoptions' => ['sopt' => $operators],
8731
                    ],
8732
                    [
8733
                        'name' => 'display_start_date',
8734
                        'index' => 'display_start_date',
8735
                        'align' => 'left',
8736
                        'search' => 'true',
8737
                        'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators],
8738
                    ],
8739
                    [
8740
                        'name' => 'display_end_date',
8741
                        'index' => 'display_end_date',
8742
                        'align' => 'left',
8743
                        'search' => 'true',
8744
                        'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators],
8745
                    ],
8746
                    [
8747
                        'name' => 'coach_name',
8748
                        'index' => 'coach_name',
8749
                        'align' => 'left',
8750
                        'search' => 'false',
8751
                        'searchoptions' => ['sopt' => $operators],
8752
                    ],
8753
                    [
8754
                        'name' => 'session_active',
8755
                        'index' => 'session_active',
8756
                        'align' => 'left',
8757
                        'search' => 'true',
8758
                        'stype' => 'select',
8759
                        // for the bottom bar
8760
                        'searchoptions' => [
8761
                            'defaultValue' => '1',
8762
                            'value' => '1:'.get_lang('Active').';0:'.get_lang('Inactive'),
8763
                        ],
8764
                        // for the top bar
8765
                        'editoptions' => [
8766
                            'value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang(
8767
                                    'Inactive'
8768
                                ),
8769
                        ],
8770
                    ],
8771
                    [
8772
                        'name' => 'visibility',
8773
                        'index' => 'visibility',
8774
                        'align' => 'left',
8775
                        'search' => 'false',
8776
                    ],
8777
                    [
8778
                        'name' => 'course_title',
8779
                        'index' => 'course_title',
8780
                        'hidden' => 'true',
8781
                        'search' => 'true',
8782
                        'searchoptions' => ['searchhidden' => 'true', 'sopt' => $operators],
8783
                    ],
8784
                ];
8785
8786
                break;
8787
8788
            case 'custom':
8789
                $columns = [
8790
                    '#',
8791
                    get_lang('Title'),
8792
                    get_lang('Category'),
8793
                    get_lang('Start date to display'),
8794
                    get_lang('End date to display'),
8795
                    get_lang('Visibility'),
8796
                ];
8797
                $columnModel = [
8798
                    [
8799
                        'name' => 'id',
8800
                        'index' => 's.id',
8801
                        'hidden' => 'true',
8802
                    ],
8803
                    [
8804
                        'name' => 'title',
8805
                        'index' => 's.title',
8806
                        'width' => '160',
8807
                        'align' => 'left',
8808
                        'search' => 'true',
8809
                        'searchoptions' => ['sopt' => $operators],
8810
                    ],
8811
                    [
8812
                        'name' => 'category_name',
8813
                        'index' => 'category_name',
8814
                        'align' => 'left',
8815
                        'search' => 'true',
8816
                        'searchoptions' => ['sopt' => $operators],
8817
                    ],
8818
                    [
8819
                        'name' => 'display_start_date',
8820
                        'index' => 'display_start_date',
8821
                        'align' => 'left',
8822
                        'search' => 'true',
8823
                        'searchoptions' => [
8824
                            'dataInit' => 'date_pick_today',
8825
                            'sopt' => $date_operators,
8826
                        ],
8827
                    ],
8828
                    [
8829
                        'name' => 'display_end_date',
8830
                        'index' => 'display_end_date',
8831
                        'align' => 'left',
8832
                        'search' => 'true',
8833
                        'searchoptions' => [
8834
                            'dataInit' => 'date_pick_one_month',
8835
                            'sopt' => $date_operators,
8836
                        ],
8837
                    ],
8838
                    [
8839
                        'name' => 'visibility',
8840
                        'index' => 'visibility',
8841
                        'align' => 'left',
8842
                        'search' => 'false',
8843
                    ],
8844
                ];
8845
8846
                if ($showCount) {
8847
                    $columns[] = get_lang('Users');
8848
                    $columnModel[] = [
8849
                        'name' => 'users',
8850
                        'index' => 'users',
8851
                        'align' => 'left',
8852
                        'search' => 'false',
8853
                    ];
8854
8855
                    // ofaj
8856
                    $columns[] = get_lang('Teachers');
8857
                    $columnModel[] = [
8858
                        'name' => 'teachers',
8859
                        'index' => 'teachers',
8860
                        'align' => 'left',
8861
                        'search' => 'false',
8862
                    ];
8863
                }
8864
8865
                $columns[] = get_lang('Session status');
8866
                $list = self::getStatusList();
8867
                $listToString = '';
8868
                foreach ($list as $statusId => $status) {
8869
                    $listToString .= $statusId.':'.$status.';';
8870
                }
8871
8872
                $columnModel[] = [
8873
                    'name' => 'status',
8874
                    'index' => 'status',
8875
                    'align' => 'left',
8876
                    'search' => 'true',
8877
                    'stype' => 'select',
8878
                    // for the bottom bar
8879
                    'searchoptions' => [
8880
                        'defaultValue' => '1',
8881
                        'value' => $listToString,
8882
                    ],
8883
                ];
8884
8885
                break;
8886
        }
8887
8888
        if (!empty($extraFields)) {
8889
            foreach ($extraFields as $field) {
8890
                $columns[] = $field['display_text'];
8891
                $columnModel[] = [
8892
                    'name' => $field['variable'],
8893
                    'index' => $field['variable'],
8894
                    'align' => 'center',
8895
                    'search' => 'false',
8896
                ];
8897
            }
8898
        }
8899
8900
        // Inject extra session fields
8901
        $rules = [];
8902
        if ($addExtraFields) {
8903
            $sessionField = new ExtraFieldModel('session');
8904
            $rules = $sessionField->getRules($columns, $columnModel);
8905
        }
8906
8907
        if (!in_array('actions', array_column($columnModel, 'name'))) {
8908
            $columnModel[] = [
8909
                'name' => 'actions',
8910
                'index' => 'actions',
8911
                'align' => 'left',
8912
                'formatter' => 'action_formatter',
8913
                'sortable' => 'false',
8914
                'search' => 'false',
8915
            ];
8916
            $columns[] = get_lang('Actions');
8917
        }
8918
8919
        $columnName = [];
8920
        foreach ($columnModel as $col) {
8921
            $columnName[] = $col['name'];
8922
        }
8923
8924
        $return = [
8925
            'columns' => $columns,
8926
            'column_model' => $columnModel,
8927
            'rules' => $rules,
8928
            'simple_column_name' => $columnName,
8929
        ];
8930
8931
        return $return;
8932
    }
8933
8934
    /**
8935
     * Converts all dates sent through the param array (given form) to correct dates with timezones.
8936
     *
8937
     * @param array The dates The same array, with times converted
8938
     * @param bool $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
8939
     *
8940
     * @return array The same array, with times converted
8941
     */
8942
    public static function convert_dates_to_local($params, $applyFormat = false)
8943
    {
8944
        if (!is_array($params)) {
8945
            return false;
8946
        }
8947
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
8948
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
8949
8950
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
8951
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
8952
8953
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
8954
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
8955
8956
        if ($applyFormat) {
8957
            if (isset($params['display_start_date'])) {
8958
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
8959
            }
8960
8961
            if (isset($params['display_end_date'])) {
8962
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
8963
            }
8964
8965
            if (isset($params['access_start_date'])) {
8966
                $params['access_start_date'] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
8967
            }
8968
8969
            if (isset($params['access_end_date'])) {
8970
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
8971
            }
8972
8973
            if (isset($params['coach_access_start_date'])) {
8974
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
8975
            }
8976
8977
            if (isset($params['coach_access_end_date'])) {
8978
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
8979
            }
8980
        }
8981
8982
        return $params;
8983
    }
8984
8985
    /**
8986
     * Gets the admin session list callback of the session/session_list.php
8987
     * page with all user/details in the right fomat.
8988
     *
8989
     * @param array $options
8990
     *
8991
     * @return array Array of rows results
8992
     * @asset ('a') === false
8993
     */
8994
    public static function get_sessions_admin_complete($options = [])
8995
    {
8996
        if (!is_array($options)) {
8997
            return false;
8998
        }
8999
9000
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
9001
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
9002
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
9003
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9004
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
9005
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9006
9007
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
9008
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
9009
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
9010
9011
        $where = 'WHERE 1 = 1 ';
9012
9013
        if (!api_is_platform_admin()) {
9014
            if (api_is_session_admin() &&
9015
                'false' == api_get_setting('allow_session_admins_to_manage_all_sessions')
9016
            ) {
9017
                $user_id = api_get_user_id();
9018
                $where .= ' AND (sru.relation_type = '.Session::SESSION_ADMIN." AND sru.user_id = $user_id) ";
9019
            } else {
9020
                $where .= ' AND sru.relation_type = '.Session::GENERAL_COACH.' ';
9021
            }
9022
        }
9023
9024
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
9025
        if (api_is_western_name_order()) {
9026
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
9027
        }
9028
9029
        $today = api_get_utc_datetime();
9030
        $injectExtraFields = null;
9031
        $extra_fields_info = [];
9032
9033
        //for now only sessions
9034
        $extra_field = new ExtraFieldModel('session');
9035
        $double_fields = [];
9036
        $extra_field_option = new ExtraFieldOption('session');
9037
9038
        if (isset($options['extra'])) {
9039
            $extra_fields = $options['extra'];
9040
            if (!empty($extra_fields)) {
9041
                foreach ($extra_fields as $extra) {
9042
                    $injectExtraFields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
9043
                    if (isset($extra_fields_info[$extra['id']])) {
9044
                        $info = $extra_fields_info[$extra['id']];
9045
                    } else {
9046
                        $info = $extra_field->get($extra['id']);
9047
                        $extra_fields_info[$extra['id']] = $info;
9048
                    }
9049
9050
                    if (ExtraFieldModel::FIELD_TYPE_DOUBLE_SELECT == $info['value_type']) {
9051
                        $double_fields[$info['id']] = $info;
9052
                    }
9053
                }
9054
            }
9055
        }
9056
9057
        $options_by_double = [];
9058
        foreach ($double_fields as $double) {
9059
            $my_options = $extra_field_option->get_field_options_by_field(
9060
                $double['id'],
9061
                true
9062
            );
9063
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
9064
        }
9065
9066
        //sc.title as category_name,
9067
        $select = "
9068
                SELECT * FROM (
9069
                    SELECT DISTINCT
9070
                        IF (
9071
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
9072
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
9073
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
9074
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
9075
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
9076
                        , 1, 0) as session_active,
9077
                s.title,
9078
                s.nbr_courses,
9079
                s.nbr_users,
9080
                s.display_start_date,
9081
                s.display_end_date,
9082
                $coach_name,
9083
                access_start_date,
9084
                access_end_date,
9085
                s.visibility,
9086
                u.id as user_id,
9087
                $injectExtraFields
9088
                c.title as course_title,
9089
                s.id ";
9090
9091
        if (!empty($options['where'])) {
9092
            if (!empty($options['extra'])) {
9093
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
9094
                $options['where'] = str_replace('AND', 'OR', $options['where']);
9095
                foreach ($options['extra'] as $extra) {
9096
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
9097
                }
9098
            }
9099
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
9100
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
9101
            $options['where'] = str_replace(
9102
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
9103
                [') GROUP BY s.title HAVING session_active = 1 ', " GROUP BY s.title HAVING session_active = 1 "],
9104
                $options['where']
9105
            );
9106
9107
            $options['where'] = str_replace(
9108
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
9109
                [') GROUP BY s.title HAVING session_active = 0 ', " GROUP BY s.title HAVING session_active = '0' "],
9110
                $options['where']
9111
            );
9112
9113
            $where .= ' AND '.$options['where'];
9114
        }
9115
9116
        $limit = '';
9117
        if (!empty($options['limit'])) {
9118
            $limit = ' LIMIT '.$options['limit'];
9119
        }
9120
9121
        $query = "$select FROM $tbl_session s
9122
                    LEFT JOIN $tbl_session_field_values fv
9123
                    ON (fv.item_id = s.id)
9124
                    LEFT JOIN $extraFieldTable f
9125
                    ON f.id = fv.field_id
9126
                    LEFT JOIN $tbl_session_field_options fvo
9127
                    ON (fv.field_id = fvo.field_id)
9128
                    LEFT JOIN $tbl_session_rel_course src
9129
                    ON (src.session_id = s.id)
9130
                    LEFT JOIN $tbl_course c
9131
                    ON (src.c_id = c.id)
9132
                    LEFT JOIN $tbl_session_category sc
9133
                    ON (s.session_category_id = sc.id)
9134
                    INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
9135
                    INNER JOIN $tbl_user u
9136
                    ON sru.user_id = u.id
9137
                    $where
9138
                    $limit
9139
        ";
9140
9141
        if (api_is_multiple_url_enabled()) {
9142
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9143
            $access_url_id = api_get_current_access_url_id();
9144
            if (-1 != $access_url_id) {
9145
                $query = "$select
9146
                    FROM $tbl_session s
9147
                    LEFT JOIN $tbl_session_field_values fv
9148
                    ON (fv.item_id = s.id)
9149
                    LEFT JOIN $tbl_session_field_options fvo
9150
                    ON (fv.field_id = fvo.field_id)
9151
                    LEFT JOIN $tbl_session_rel_course src
9152
                    ON (src.session_id = s.id)
9153
                    LEFT JOIN $tbl_course c
9154
                    ON (src.c_id = c.id)
9155
                    LEFT JOIN $tbl_session_category sc
9156
                    ON (s.session_category_id = sc.id)
9157
                    INNER JOIN $tblSessionRelUser sru ON s.id = sru.session_id
9158
                    INNER JOIN $tbl_user u
9159
                    ON sru.user_id = u.id
9160
                    INNER JOIN $table_access_url_rel_session ar
9161
                    ON (ar.session_id = s.id AND ar.access_url_id = $access_url_id)
9162
                    $where
9163
                    $limit
9164
                ";
9165
            }
9166
        }
9167
9168
        $query .= ') AS s';
9169
9170
        if (!empty($options['order'])) {
9171
            $query .= ' ORDER BY '.$options['order'];
9172
        }
9173
9174
        $result = Database::query($query);
9175
9176
        $acceptIcon = Display::getMdiIcon(StateIcon::ACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Active'));
9177
9178
        $errorIcon = Display::getMdiIcon(StateIcon::INACTIVE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Inactive'));
9179
9180
        $formatted_sessions = [];
9181
        if (Database::num_rows($result)) {
9182
            $sessions = Database::store_result($result, 'ASSOC');
9183
            foreach ($sessions as $session) {
9184
                $session_id = $session['id'];
9185
                $session['title'] = Display::url($session['title'], "resume_session.php?id_session=".$session['id']);
9186
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
9187
                if (1 == $session['session_active']) {
9188
                    $session['session_active'] = $acceptIcon;
9189
                } else {
9190
                    $session['session_active'] = $errorIcon;
9191
                }
9192
9193
                $session = self::convert_dates_to_local($session);
9194
9195
                switch ($session['visibility']) {
9196
                    case SESSION_VISIBLE_READ_ONLY: //1
9197
                        $session['visibility'] = get_lang('Read only');
9198
                        break;
9199
                    case SESSION_VISIBLE:           //2
9200
                    case SESSION_AVAILABLE:         //4
9201
                        $session['visibility'] = get_lang('Visible');
9202
                        break;
9203
                    case SESSION_INVISIBLE:         //3
9204
                        $session['visibility'] = api_ucfirst(get_lang('invisible'));
9205
                        break;
9206
                }
9207
9208
                // Cleaning double selects
9209
                foreach ($session as $key => &$value) {
9210
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
9211
                        $options = explode('::', $value);
9212
                    }
9213
                    $original_key = $key;
9214
9215
                    if (false === strpos($key, '_second')) {
9216
                    } else {
9217
                        $key = str_replace('_second', '', $key);
9218
                    }
9219
9220
                    if (isset($options_by_double[$key])) {
9221
                        if (isset($options[0])) {
9222
                            if (isset($options_by_double[$key][$options[0]])) {
9223
                                if (false === strpos($original_key, '_second')) {
9224
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
9225
                                } else {
9226
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
9227
                                }
9228
                            }
9229
                        }
9230
                    }
9231
                }
9232
9233
                // Magic filter
9234
                if (isset($formatted_sessions[$session_id])) {
9235
                    $formatted_sessions[$session_id] = self::compareArraysToMerge(
9236
                        $formatted_sessions[$session_id],
9237
                        $session
9238
                    );
9239
                } else {
9240
                    $formatted_sessions[$session_id] = $session;
9241
                }
9242
            }
9243
        }
9244
9245
        return $formatted_sessions;
9246
    }
9247
9248
    /**
9249
     * Compare two arrays.
9250
     *
9251
     * @param array $array1
9252
     * @param array $array2
9253
     *
9254
     * @return array
9255
     */
9256
    public static function compareArraysToMerge($array1, $array2)
9257
    {
9258
        if (empty($array2)) {
9259
            return $array1;
9260
        }
9261
        foreach ($array1 as $key => $item) {
9262
            if (!isset($array1[$key])) {
9263
                //My string is empty try the other one
9264
                if (isset($array2[$key]) && !empty($array2[$key])) {
9265
                    $array1[$key] = $array2[$key];
9266
                }
9267
            }
9268
        }
9269
9270
        return $array1;
9271
    }
9272
9273
    /**
9274
     * Get link to the admin page for this session.
9275
     *
9276
     * @param int $id Session ID
9277
     *
9278
     * @return mixed URL to the admin page to manage the session, or false on error
9279
     */
9280
    public static function getAdminPath($id)
9281
    {
9282
        $id = (int) $id;
9283
        $session = self::fetch($id);
9284
        if (empty($session)) {
9285
            return false;
9286
        }
9287
9288
        return api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$id;
9289
    }
9290
9291
    /**
9292
     * Get link to the user page for this session.
9293
     * If a course is provided, build the link to the course.
9294
     *
9295
     * @param int $id       Session ID
9296
     * @param int $courseId Course ID (optional) in case the link has to send straight to the course
9297
     *
9298
     * @return mixed URL to the page to use the session, or false on error
9299
     */
9300
    public static function getPath($id, $courseId = 0)
9301
    {
9302
        $id = (int) $id;
9303
        $session = self::fetch($id);
9304
        if (empty($session)) {
9305
            return false;
9306
        }
9307
        if (empty($courseId)) {
9308
            return api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$id;
9309
        } else {
9310
            $courseInfo = api_get_course_info_by_id($courseId);
9311
            if ($courseInfo) {
9312
                return $courseInfo['course_public_url'].'?id_session='.$id;
9313
            }
9314
        }
9315
9316
        return false;
9317
    }
9318
9319
    /**
9320
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9321
     * where course id_course is in sessions id_session1, id_session2
9322
     * for course where user is coach
9323
     * i.e. coach for the course or
9324
     * main coach for a session the course is in
9325
     * for a session category (or woth no session category if empty).
9326
     *
9327
     * @param int $userId
9328
     *
9329
     * @return array
9330
     */
9331
    public static function getSessionCourseForUser($userId)
9332
    {
9333
        // list of COURSES where user is COURSE session coach
9334
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
9335
        // list of courses where user is MAIN session coach
9336
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
9337
        // merge these 2 array
9338
        $listResCourseSession = $listCourseCourseCoachSession;
9339
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
9340
            if (isset($listResCourseSession[$courseId2])) {
9341
                // if sessionId array exists for this course
9342
                // same courseId, merge the list of session
9343
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
9344
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
9345
                        $listResCourseSession[$courseId2][] = $sessionId2;
9346
                    }
9347
                }
9348
            } else {
9349
                $listResCourseSession[$courseId2] = $listSessionId2;
9350
            }
9351
        }
9352
9353
        return $listResCourseSession;
9354
    }
9355
9356
    /**
9357
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9358
     * where course id_course is in sessions id_session1, id_session2.
9359
     *
9360
     * @param int $userId
9361
     *
9362
     * @return array
9363
     */
9364
    public static function getCoursesForCourseSessionCoach($userId)
9365
    {
9366
        $userId = (int) $userId;
9367
        $listResCourseSession = [];
9368
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9369
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9370
9371
        $sql = "SELECT session_id, c_id, c.id
9372
                FROM $tblSessionRelCourseRelUser srcru
9373
                LEFT JOIN $tblCourse c
9374
                ON c.id = srcru.c_id
9375
                WHERE
9376
                    srcru.user_id = $userId AND
9377
                    srcru.status = ".Session::COURSE_COACH;
9378
9379
        $res = Database::query($sql);
9380
9381
        while ($data = Database::fetch_assoc($res)) {
9382
            if (api_get_session_visibility($data['session_id'])) {
9383
                if (!isset($listResCourseSession[$data['id']])) {
9384
                    $listResCourseSession[$data['id']] = [];
9385
                }
9386
                $listResCourseSession[$data['id']][] = $data['session_id'];
9387
            }
9388
        }
9389
9390
        return $listResCourseSession;
9391
    }
9392
9393
    /**
9394
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9395
     * where course id_course is in sessions id_session1, id_session2.
9396
     *
9397
     * @param $userId
9398
     *
9399
     * @return array
9400
     */
9401
    public static function getCoursesForMainSessionCoach($userId)
9402
    {
9403
        $userId = (int) $userId;
9404
        $user = api_get_user_entity($userId);
9405
        $listResCourseSession = [];
9406
9407
        $sessions = $user->getSessionsAsGeneralCoach();
9408
9409
        foreach ($sessions as $session) {
9410
            $sessionId = $session->getId();
9411
            $listCoursesInSession = self::getCoursesInSession($sessionId);
9412
            foreach ($listCoursesInSession as $i => $courseId) {
9413
                if (api_get_session_visibility($sessionId)) {
9414
                    if (!isset($listResCourseSession[$courseId])) {
9415
                        $listResCourseSession[$courseId] = [];
9416
                    }
9417
                    $listResCourseSession[$courseId][] = $sessionId;
9418
                }
9419
            }
9420
        }
9421
9422
        return $listResCourseSession;
9423
    }
9424
9425
    /**
9426
     * Return an array of course_id used in session $sessionId.
9427
     *
9428
     * @param $sessionId
9429
     *
9430
     * @return array
9431
     */
9432
    public static function getCoursesInSession($sessionId)
9433
    {
9434
        if (empty($sessionId)) {
9435
            return [];
9436
        }
9437
9438
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9439
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9440
9441
        // list of course in this session
9442
        $sql = "SELECT session_id, c.id
9443
                FROM $tblSessionRelCourse src
9444
                LEFT JOIN $tblCourse c
9445
                ON c.id = src.c_id
9446
                WHERE session_id = ".intval($sessionId);
9447
        $res = Database::query($sql);
9448
9449
        $listResultsCourseId = [];
9450
        while ($data = Database::fetch_assoc($res)) {
9451
            $listResultsCourseId[] = $data['id'];
9452
        }
9453
9454
        return $listResultsCourseId;
9455
    }
9456
9457
    /**
9458
     * Return an array of courses in session for user
9459
     * and for each courses the list of session that use this course for user.
9460
     *
9461
     * [0] => array
9462
     *      userCatId
9463
     *      userCatTitle
9464
     *      courseInUserCatList
9465
     *          [0] => array
9466
     *              courseId
9467
     *              title
9468
     *              courseCode
9469
     *              sessionCatList
9470
     *                  [0] => array
9471
     *                      catSessionId
9472
     *                      catSessionName
9473
     *                      sessionList
9474
     *                          [0] => array
9475
     *                              sessionId
9476
     *                              sessionName
9477
     *
9478
     * @param int $userId
9479
     *
9480
     * @return array
9481
     */
9482
    public static function getNamedSessionCourseForCoach($userId)
9483
    {
9484
        $listResults = [];
9485
        $listCourseSession = self::getSessionCourseForUser($userId);
9486
        foreach ($listCourseSession as $courseId => $listSessionId) {
9487
            // Course info
9488
            $courseInfo = api_get_course_info_by_id($courseId);
9489
            $listOneCourse = [];
9490
            $listOneCourse['courseId'] = $courseId;
9491
            $listOneCourse['title'] = $courseInfo['title'];
9492
            //$listOneCourse['courseCode'] = $courseInfo['code'];
9493
            $listOneCourse['course'] = $courseInfo;
9494
            $listOneCourse['sessionCatList'] = [];
9495
            $listCat = [];
9496
            foreach ($listSessionId as $i => $sessionId) {
9497
                // here we got all session for this course
9498
                // lets check there session categories
9499
                $sessionInfo = self::fetch($sessionId);
9500
                $catId = $sessionInfo['session_category_id'];
9501
                if (!isset($listCat[$catId])) {
9502
                    $listCatInfo = self::get_session_category($catId);
9503
                    if ($listCatInfo) {
9504
                        $listCat[$catId] = [];
9505
                        $listCat[$catId]['catSessionId'] = $catId;
9506
                        $listCat[$catId]['catSessionName'] = $listCatInfo['title'];
9507
                        $listCat[$catId]['sessionList'] = [];
9508
                    }
9509
                }
9510
                $listSessionInfo = self::fetch($sessionId);
9511
                $listSessionIdName = [
9512
                    'sessionId' => $sessionId,
9513
                    'sessionName' => $listSessionInfo['title'],
9514
                ];
9515
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
9516
            }
9517
            // sort $listCat by catSessionName
9518
            usort($listCat, 'self::compareBySessionName');
9519
            // in each catSession sort sessionList by sessionName
9520
            foreach ($listCat as $i => $listCatSessionInfo) {
9521
                $listSessionList = $listCatSessionInfo['sessionList'];
9522
                usort($listSessionList, 'self::compareCatSessionInfo');
9523
                $listCat[$i]['sessionList'] = $listSessionList;
9524
            }
9525
9526
            $listOneCourse['sessionCatList'] = $listCat;
9527
            //$listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
9528
        }
9529
9530
        // sort by user course cat
9531
        uasort($listResults, 'self::compareByUserCourseCat');
9532
9533
        // sort by course title
9534
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
9535
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
9536
            uasort($courseInUserCatList, 'self::compareByCourse');
9537
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
9538
        }
9539
9540
        return $listResults;
9541
    }
9542
9543
    /**
9544
     * @param int $userId
9545
     * @param int $courseId
9546
     *
9547
     * @return array
9548
     */
9549
    public static function searchCourseInSessionsFromUser($userId, $courseId)
9550
    {
9551
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9552
        $userId = (int) $userId;
9553
        $courseId = (int) $courseId;
9554
        if (empty($userId) || empty($courseId)) {
9555
            return [];
9556
        }
9557
9558
        $sql = "SELECT * FROM $table
9559
                WHERE c_id = $courseId AND user_id = $userId";
9560
        $result = Database::query($sql);
9561
9562
        return Database::store_result($result, 'ASSOC');
9563
    }
9564
9565
    /**
9566
     * Subscribe and redirect to session after inscription.
9567
     */
9568
    public static function redirectToSession()
9569
    {
9570
        $sessionId = (int) ChamiloSession::read('session_redirect');
9571
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
9572
        if ($sessionId) {
9573
            $sessionInfo = api_get_session_info($sessionId);
9574
            if (!empty($sessionInfo)) {
9575
                $userId = api_get_user_id();
9576
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
9577
                if ($response) {
9578
                    $urlToRedirect = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
9579
                    if (!empty($onlyOneCourseSessionToRedirect)) {
9580
                        $urlToRedirect = api_get_path(WEB_PATH).
9581
                            'courses/'.$onlyOneCourseSessionToRedirect.'/index.php?id_session='.$sessionId;
9582
                    }
9583
9584
                    header('Location: '.$urlToRedirect);
9585
                    exit;
9586
                }
9587
            }
9588
        }
9589
    }
9590
9591
    /**
9592
     * @return int
9593
     */
9594
    public static function getCountUsersInCourseSession(Course $course, Session $session)
9595
    {
9596
        $url = api_get_url_entity(api_get_current_access_url_id());
9597
9598
        return Database::getManager()
9599
            ->createQuery("
9600
                SELECT COUNT(scu)
9601
                FROM ChamiloCoreBundle:SessionRelCourseRelUser scu
9602
                INNER JOIN ChamiloCoreBundle:SessionRelUser su
9603
                    WITH scu.user = su.user
9604
                    AND scu.session = su.session
9605
                INNER JOIN ChamiloCoreBundle:AccessUrlRelUser a
9606
                    WITH a.user = su.user
9607
                WHERE
9608
                    scu.course = :course AND
9609
                    su.relationType <> :relationType AND
9610
                    scu.session = :session AND
9611
                    a.url = :url
9612
            ")
9613
            ->setParameters([
9614
                'course' => $course->getId(),
9615
                'relationType' => Session::DRH,
9616
                'session' => $session->getId(),
9617
                'url' => $url,
9618
            ])
9619
            ->getSingleScalarResult();
9620
    }
9621
9622
    /**
9623
     * Get course IDs where user in not subscribed in session.
9624
     *
9625
     * @return array
9626
     */
9627
    public static function getAvoidedCoursesInSession(User $user, Session $session)
9628
    {
9629
        $courseIds = [];
9630
9631
        /** @var SessionRelCourse $sessionCourse */
9632
        foreach ($session->getCourses() as $sessionCourse) {
9633
            /** @var Course $course */
9634
            $course = $sessionCourse->getCourse();
9635
9636
            if ($session->getUserInCourse($user, $course)->count()) {
9637
                continue;
9638
            }
9639
9640
            $courseIds[] = $course->getId();
9641
        }
9642
9643
        return $courseIds;
9644
    }
9645
9646
    /**
9647
     * @param int             $userId
9648
     * @param int             $sessionId
9649
     * @param ExtraFieldValue $extraFieldValue
9650
     * @param string          $collapsableLink
9651
     *
9652
     * @return array
9653
     */
9654
    public static function getCollapsableData($userId, $sessionId, $extraFieldValue, $collapsableLink)
9655
    {
9656
        $collapsed = 0;
9657
9658
        // Get default collapsed value in extra field
9659
        $value = $extraFieldValue->get_values_by_handler_and_field_variable($sessionId, 'collapsed');
9660
        if (!empty($value) && isset($value['value'])) {
9661
            $collapsed = $value['value'];
9662
        }
9663
9664
        $userRelSession = self::getUserSession($userId, $sessionId);
9665
9666
        if ($userRelSession) {
9667
            if (isset($userRelSession['collapsed']) && '' != $userRelSession['collapsed']) {
9668
                $collapsed = $userRelSession['collapsed'];
9669
            }
9670
        } else {
9671
            return ['collapsed' => $collapsed, 'collapsable_link' => '&nbsp;'];
9672
        }
9673
9674
        $link = $collapsableLink.'&session_id='.$sessionId.'&value=1';
9675
        $image = '<i class="fa fa-folder-open"></i>';
9676
        if (1 == $collapsed) {
9677
            $link = $collapsableLink.'&session_id='.$sessionId.'&value=0';
9678
            $image = '<i class="fa fa-folder"></i>';
9679
        }
9680
9681
        $link = Display::url(
9682
            $image,
9683
            $link
9684
        );
9685
9686
        return ['collapsed' => $collapsed, 'collapsable_link' => $link];
9687
    }
9688
9689
    /**
9690
     * Converts "start date" and "end date" to "From start date to end date" string.
9691
     *
9692
     * @param string|DateTime $startDate
9693
     * @param string|DateTime $endDate
9694
     * @param bool   $showTime
9695
     * @param bool   $dateHuman
9696
     *
9697
     * @return string
9698
     */
9699
    public static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
9700
    {
9701
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
9702
        $startDateToLocal = api_get_local_time(
9703
            $startDate,
9704
            null,
9705
            null,
9706
            true,
9707
            $showTime,
9708
            $dateHuman
9709
        );
9710
        $endDateToLocal = api_get_local_time(
9711
            $endDate,
9712
            null,
9713
            null,
9714
            true,
9715
            $showTime,
9716
            $dateHuman
9717
        );
9718
9719
        $format = $showTime ? DATE_TIME_FORMAT_LONG_24H : DATE_FORMAT_LONG_NO_DAY;
9720
9721
        $result = '';
9722
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
9723
            $result = sprintf(
9724
                get_lang('From %s to %s'),
9725
                api_format_date($startDateToLocal, $format),
9726
                api_format_date($endDateToLocal, $format)
9727
            );
9728
        } else {
9729
            if (!empty($startDateToLocal)) {
9730
                $result = get_lang('From').' '.api_format_date($startDateToLocal, $format);
9731
            }
9732
            if (!empty($endDateToLocal)) {
9733
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, $format);
9734
            }
9735
        }
9736
        if (empty($result)) {
9737
            $result = get_lang('No time limits');
9738
        }
9739
9740
        return $result;
9741
    }
9742
9743
    /**
9744
     * @param int $id
9745
     */
9746
    public static function getSessionChangeUserReason($id): string
9747
    {
9748
        $reasons = self::getSessionChangeUserReasons();
9749
9750
        return $reasons[$id] ?? '';
9751
    }
9752
9753
    public static function getSessionChangeUserReasons(): array
9754
    {
9755
        return [
9756
            self::SESSION_CHANGE_USER_REASON_SCHEDULE => get_lang('ScheduleChanged'),
9757
            self::SESSION_CHANGE_USER_REASON_CLASSROOM => get_lang('ClassRoomChanged'),
9758
            self::SESSION_CHANGE_USER_REASON_LOCATION => get_lang('LocationChanged'),
9759
            //self::SESSION_CHANGE_USER_REASON_ENROLLMENT_ANNULATION => get_lang('EnrollmentAnnulation'),
9760
        ];
9761
    }
9762
9763
    public static function getStatusList()
9764
    {
9765
        return [
9766
            self::STATUS_PLANNED => get_lang('Planned'),
9767
            self::STATUS_PROGRESS => get_lang('InProgress'),
9768
            self::STATUS_FINISHED => get_lang('Finished'),
9769
            self::STATUS_CANCELLED => get_lang('Cancelled'),
9770
        ];
9771
    }
9772
9773
    public static function getStatusLabel($status)
9774
    {
9775
        $list = self::getStatusList();
9776
9777
        if (!isset($list[$status])) {
9778
            return get_lang('No status');
9779
        }
9780
9781
        return $list[$status];
9782
    }
9783
9784
    public static function getDefaultSessionTab()
9785
    {
9786
        $default = 'all';
9787
        $view = api_get_setting('session.default_session_list_view');
9788
9789
        if ('false' !== $view && !empty($view)) {
9790
            $default = $view;
9791
        }
9792
9793
        return $default;
9794
    }
9795
9796
    /**
9797
     * @return array
9798
     */
9799
    public static function getSessionListTabs($listType)
9800
    {
9801
        $tabs = [
9802
            [
9803
                'content' => get_lang('All sessions'),
9804
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=all',
9805
            ],
9806
            [
9807
                'content' => get_lang('Active sessions'),
9808
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=active',
9809
            ],
9810
            [
9811
                'content' => get_lang('Closed sessions'),
9812
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=close',
9813
            ],
9814
            [
9815
                'content' => get_lang('Custom list'),
9816
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=custom',
9817
            ],
9818
            /*[
9819
                'content' => get_lang('Complete'),
9820
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list_simple.php?list_type=complete',
9821
            ],*/
9822
        ];
9823
        $default = null;
9824
        switch ($listType) {
9825
            case 'all':
9826
                $default = 1;
9827
                break;
9828
            case 'active':
9829
                $default = 2;
9830
                break;
9831
            case 'close':
9832
                $default = 3;
9833
                break;
9834
            case 'custom':
9835
                $default = 4;
9836
                break;
9837
        }
9838
9839
        return Display::tabsOnlyLink($tabs, $default);
9840
    }
9841
9842
    /**
9843
     * Check if a session is followed by human resources manager.
9844
     *
9845
     * @param int $sessionId
9846
     * @param int $userId
9847
     *
9848
     * @return bool
9849
     */
9850
    public static function isSessionFollowedByDrh($sessionId, $userId)
9851
    {
9852
        $userId = (int) $userId;
9853
        $sessionId = (int) $sessionId;
9854
9855
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9856
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9857
9858
        if (api_is_multiple_url_enabled()) {
9859
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9860
9861
            $sql = "SELECT s.id FROM $tblSession s
9862
                INNER JOIN $tblSessionRelUser sru ON (sru.session_id = s.id)
9863
                LEFT JOIN $tblSessionRelAccessUrl a ON (s.id = a.session_id)
9864
                WHERE
9865
                    sru.user_id = '$userId' AND
9866
                    sru.session_id = '$sessionId' AND
9867
                    sru.relation_type = '".Session::DRH."' AND
9868
                    access_url_id = ".api_get_current_access_url_id();
9869
        } else {
9870
            $sql = "SELECT s.id FROM $tblSession s
9871
                INNER JOIN $tblSessionRelUser sru ON sru.session_id = s.id
9872
                WHERE
9873
                    sru.user_id = '$userId' AND
9874
                    sru.session_id = '$sessionId' AND
9875
                    sru.relation_type = '".Session::DRH."'";
9876
        }
9877
9878
        $result = Database::query($sql);
9879
9880
        return Database::num_rows($result) > 0;
9881
    }
9882
9883
    /**
9884
     * Add a warning message when session is read-only mode.
9885
     */
9886
    public static function addFlashSessionReadOnly()
9887
    {
9888
        if (api_get_session_id() && !api_is_allowed_to_session_edit()) {
9889
            Display::addFlash(
9890
                Display::return_message(get_lang('The session is read only'), 'warning')
9891
            );
9892
        }
9893
    }
9894
9895
    public static function insertUsersInCourses(array $studentIds, array $courseIds, int $sessionId)
9896
    {
9897
        $session = api_get_session_entity($sessionId);
9898
9899
        foreach ($courseIds as $courseId) {
9900
            self::insertUsersInCourse($studentIds, $courseId, $sessionId, [], false);
9901
        }
9902
9903
        foreach ($studentIds as $studentId) {
9904
            $user = api_get_user_entity($studentId);
9905
9906
            $session->addUserInSession(Session::STUDENT, $user);
9907
        }
9908
    }
9909
9910
    /**
9911
     * @throws \Doctrine\ORM\Exception\ORMException
9912
     */
9913
    public static function insertUsersInCourse(
9914
        array $studentIds,
9915
        int $courseId,
9916
        int $sessionId,
9917
        array $relationInfo = [],
9918
        bool $updateSession = true,
9919
        bool $sendNotification = false
9920
    ) {
9921
        $em = Database::getManager();
9922
        $course = api_get_course_entity($courseId);
9923
        $session = api_get_session_entity($sessionId);
9924
9925
        $relationInfo = array_merge(['visibility' => 0, 'status' => Session::STUDENT], $relationInfo);
9926
9927
        $usersToInsert = [];
9928
        foreach ($studentIds as $studentId) {
9929
            $user = api_get_user_entity($studentId);
9930
            $session->addUserInCourse($relationInfo['status'], $user, $course)
9931
                ->setVisibility($relationInfo['visibility']);
9932
9933
            Event::logUserSubscribedInCourseSession($user, $course, $session);
9934
9935
            if ($updateSession) {
9936
                if (!$session->hasUserInSession($user, Session::STUDENT)) {
9937
                    $session->addUserInSession(Session::STUDENT, $user);
9938
                }
9939
            }
9940
9941
            $usersToInsert[] = $studentId;
9942
        }
9943
9944
        $em->persist($session);
9945
        $em->flush();
9946
9947
        if ($sendNotification && !empty($usersToInsert)) {
9948
            foreach ($usersToInsert as $userId) {
9949
                $user = api_get_user_entity($userId);
9950
                $courseTitle = $course->getTitle();
9951
                $sessionTitle = $session->getTitle();
9952
9953
                $subject = sprintf(get_lang('You have been enrolled in the course %s for the session %s'), $courseTitle, $sessionTitle);
9954
                $message = sprintf(
9955
                    get_lang('Hello %s, you have been enrolled in the course %s for the session %s.'),
9956
                    UserManager::formatUserFullName($user, true),
9957
                    $courseTitle,
9958
                    $sessionTitle
9959
                );
9960
9961
                MessageManager::send_message_simple(
9962
                    $userId,
9963
                    $subject,
9964
                    $message,
9965
                    api_get_user_id(),
9966
                    false,
9967
                    true
9968
                );
9969
            }
9970
        }
9971
    }
9972
9973
    public static function getCareersFromSession(int $sessionId): array
9974
    {
9975
        $extraFieldValueSession = new ExtraFieldValue('session');
9976
        $extraFieldValueCareer = new ExtraFieldValue('career');
9977
9978
        $value = $extraFieldValueSession->get_values_by_handler_and_field_variable($sessionId, 'careerid');
9979
        $careers = [];
9980
        if (isset($value['value']) && !empty($value['value'])) {
9981
            $careerList = str_replace(['[', ']'], '', $value['value']);
9982
            $careerList = explode(',', $careerList);
9983
9984
            $careerManager = new Career();
9985
            foreach ($careerList as $career) {
9986
                $careerIdValue = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
9987
                    'external_career_id',
9988
                    $career
9989
                );
9990
                if (isset($careerIdValue['item_id']) && !empty($careerIdValue['item_id'])) {
9991
                    $finalCareerId = $careerIdValue['item_id'];
9992
                    $careerInfo = $careerManager->get($finalCareerId);
9993
                    if (!empty($careerInfo)) {
9994
                        $careers[] = $careerInfo;
9995
                    }
9996
                }
9997
            }
9998
        }
9999
10000
        return $careers;
10001
    }
10002
10003
    public static function getCareerDiagramPerSessionList($sessionList, $userId)
10004
    {
10005
        if (empty($sessionList) || empty($userId)) {
10006
            return '';
10007
        }
10008
10009
        $userId = (int) $userId;
10010
        $content = Display::page_subheader(get_lang('Ongoing training'));
10011
        $content .= '
10012
           <script>
10013
            resizeIframe = function(iFrame) {
10014
                iFrame.height = iFrame.contentWindow.document.body.scrollHeight + 20;
10015
            }
10016
            </script>
10017
        ';
10018
        $careersAdded = [];
10019
        foreach ($sessionList as $sessionId) {
10020
            $visibility = api_get_session_visibility($sessionId, null, false, $userId);
10021
            if (SESSION_AVAILABLE === $visibility) {
10022
                $careerList = self::getCareersFromSession($sessionId);
10023
                if (empty($careerList)) {
10024
                    continue;
10025
                }
10026
                foreach ($careerList as $career) {
10027
                    $careerId = $career['id'];
10028
                    if (!in_array($careerId, $careersAdded)) {
10029
                        $careersAdded[] = $careerId;
10030
                        $careerUrl = api_get_path(WEB_CODE_PATH).'user/career_diagram.php?iframe=1&career_id='.$career['id'].'&user_id='.$userId;
10031
                        $content .= '
10032
                            <iframe
10033
                                onload="resizeIframe(this)"
10034
                                style="width:100%;"
10035
                                border="0"
10036
                                frameborder="0"
10037
                                scrolling="no"
10038
                                src="'.$careerUrl.'"
10039
                            ></iframe>';
10040
                    }
10041
                }
10042
            }
10043
        }
10044
10045
        return $content;
10046
    }
10047
10048
    private static function allowed(?Session $session = null): bool
10049
    {
10050
        if (api_is_platform_admin()) {
10051
            return true;
10052
        }
10053
10054
        if (null === $session) {
10055
            return false;
10056
        }
10057
10058
        $user = api_get_user_entity();
10059
10060
        if (api_is_session_admin() &&
10061
            'true' !== api_get_setting('session.allow_session_admins_to_manage_all_sessions')
10062
        ) {
10063
10064
            if (!$session->hasUserAsSessionAdmin($user)) {
10065
                return false;
10066
            }
10067
        }
10068
10069
        if (api_is_teacher() &&
10070
            'true' === api_get_setting('session.allow_teachers_to_create_sessions')
10071
        ) {
10072
            if (!$session->hasUserAsGeneralCoach($user))  {
10073
                return false;
10074
            }
10075
        }
10076
10077
        return true;
10078
    }
10079
10080
    /**
10081
     * Add classes (by their names) to a session.
10082
     *
10083
     * @param int   $sessionId
10084
     * @param array $classesNames
10085
     * @param bool  $deleteClassSessions Optional. Empty the session list for the usergroup (class)
10086
     */
10087
    private static function addClassesByName($sessionId, $classesNames, $deleteClassSessions = true)
10088
    {
10089
        if (!$classesNames) {
10090
            return;
10091
        }
10092
10093
        $usergroup = new UserGroupModel();
10094
10095
        foreach ($classesNames as $className) {
10096
            if (empty($className)) {
10097
                continue;
10098
            }
10099
10100
            $usergroup->subscribe_sessions_to_usergroup(
10101
                $usergroup->getIdByName($className),
10102
                [$sessionId],
10103
                $deleteClassSessions
10104
            );
10105
        }
10106
    }
10107
10108
    /**
10109
     * @param array $listA
10110
     * @param array $listB
10111
     *
10112
     * @return int
10113
     */
10114
    private static function compareCatSessionInfo($listA, $listB)
10115
    {
10116
        if ($listA['sessionName'] == $listB['sessionName']) {
10117
            return 0;
10118
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
10119
            return 1;
10120
        } else {
10121
            return -1;
10122
        }
10123
    }
10124
10125
    /**
10126
     * @param array $listA
10127
     * @param array $listB
10128
     *
10129
     * @return int
10130
     */
10131
    private static function compareBySessionName($listA, $listB)
10132
    {
10133
        if ('' == $listB['catSessionName']) {
10134
            return -1;
10135
        } elseif ('' == $listA['catSessionName']) {
10136
            return 1;
10137
        } elseif ($listA['catSessionName'] == $listB['catSessionName']) {
10138
            return 0;
10139
        } elseif ($listA['catSessionName'] > $listB['catSessionName']) {
10140
            return 1;
10141
        } else {
10142
            return -1;
10143
        }
10144
    }
10145
10146
    /**
10147
     * @param array $listA
10148
     * @param array $listB
10149
     *
10150
     * @return int
10151
     */
10152
    private static function compareByUserCourseCat($listA, $listB)
10153
    {
10154
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
10155
            return 0;
10156
        } elseif ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
10157
            return 1;
10158
        } else {
10159
            return -1;
10160
        }
10161
    }
10162
10163
    /**
10164
     * @param array $listA
10165
     * @param array $listB
10166
     *
10167
     * @return int
10168
     */
10169
    private static function compareByCourse($listA, $listB)
10170
    {
10171
        if ($listA['title'] == $listB['title']) {
10172
            return 0;
10173
        } elseif ($listA['title'] > $listB['title']) {
10174
            return 1;
10175
        } else {
10176
            return -1;
10177
        }
10178
    }
10179
10180
    public static function getGeneralCoachesIdForSession(int $sessionId): array
10181
    {
10182
        return api_get_session_entity($sessionId)
10183
            ->getGeneralCoaches()
10184
            ->map(fn(User $user) => $user->getId())
10185
            ->getValues();
10186
    }
10187
10188
    public static function getGeneralCoachesNamesForSession(int $sessionId): array
10189
    {
10190
        return api_get_session_entity($sessionId)
10191
            ->getGeneralCoaches()
10192
            ->map(fn(User $user) => $user->getFullname())
10193
            ->getValues();
10194
    }
10195
10196
    public static function sessionHasSessionAdmin(int $sessionId, int $userId): bool
10197
    {
10198
        $adminIds = api_get_session_entity($sessionId)
10199
            ->getSessionAdmins()
10200
            ->map(fn(User $user) => $user->getId())
10201
            ->getValues();
10202
10203
        return in_array($userId, $adminIds);
10204
    }
10205
10206
    /**
10207
     * Retrieves all user IDs associated with a session including coaches and students.
10208
     *
10209
     * @param int $sessionId The session ID.
10210
     * @return array An array of user IDs.
10211
     */
10212
    public static function getAllUserIdsInSession(int $sessionId): array
10213
    {
10214
        $users = [];
10215
        $session = api_get_session_entity($sessionId);
10216
        if ($session) {
10217
            $courses = $session->getCourses();
10218
            if (!empty($courses)) {
10219
                foreach ($courses as $sessionRelCourse) {
10220
                    $course = $sessionRelCourse->getCourse();
10221
                    $coachSubscriptions = $session->getSessionRelCourseRelUsersByStatus($course, Session::COURSE_COACH);
10222
                    foreach ($coachSubscriptions as $coachSubscription) {
10223
                        $users[]['user_id'] = $coachSubscription->getUser()->getId();
10224
                    }
10225
10226
                    $userCourseSubscriptions = $session->getSessionRelCourseRelUsersByStatus($course, Session::STUDENT);
10227
                    foreach ($userCourseSubscriptions as $courseSubscription) {
10228
                        $users[]['user_id'] = $courseSubscription->getUser()->getId();
10229
                    }
10230
10231
                }
10232
            }
10233
10234
            $generalCoachesId = self::getGeneralCoachesIdForSession($sessionId);
10235
            if (!empty($generalCoachesId)) {
10236
                foreach ($generalCoachesId as $generalCoachId) {
10237
                    $users[]['user_id'] = $generalCoachId;
10238
                }
10239
            }
10240
        }
10241
10242
        return $users;
10243
    }
10244
}
10245