Passed
Pull Request — master (#5831)
by
unknown
07:32
created

SessionManager::get_sessions_list()   C

Complexity

Conditions 17

Size

Total Lines 91
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 53
nop 6
dl 0
loc 91
rs 5.2166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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