Passed
Push — dependabot/composer/symfony/se... ( 6a3ee0...ae0984 )
by
unknown
28:58 queued 18:58
created

SessionManager::generateSessionCourseReportData()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 84
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

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

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

Loading history...
10273
        }
10274
    }
10275
10276
    /**
10277
     * Exports session data as a ZIP file with CSVs and sends it for download.
10278
     */
10279
    public static function exportSessionsAsZip(array $sessionList): void
10280
    {
10281
        $tempZipFile = api_get_path(SYS_ARCHIVE_PATH) . api_get_unique_id() . '.zip';
10282
        $tempDir = dirname($tempZipFile);
10283
10284
        if (!is_dir($tempDir) || !is_writable($tempDir)) {
10285
            exit("The directory for creating the ZIP file does not exist or lacks write permissions: $tempDir");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

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

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

Loading history...
10291
        }
10292
10293
        foreach ($sessionList as $sessionItemId) {
10294
            $courses = SessionManager::get_course_list_by_session_id($sessionItemId);
10295
10296
            if (!empty($courses)) {
10297
                foreach ($courses as $course) {
10298
                    $courseCode = $course['course_code'];
10299
                    $courseId = $course['id'];
10300
                    $studentList = CourseManager::get_student_list_from_course_code($courseCode, true, $sessionItemId);
10301
                    $userIds = array_keys($studentList);
10302
10303
                    [$csvHeaders, $csvContent] = self::generateSessionCourseReportData($sessionItemId, $courseId, $userIds);
10304
                    array_unshift($csvContent, $csvHeaders);
10305
10306
                    $sessionInfo = api_get_session_info($sessionItemId);
10307
                    $courseInfo = api_get_course_info_by_id($courseId);
10308
                    $csvFileName = $sessionInfo['name'] . '_' . $courseInfo['name'] . '.csv';
10309
10310
                    $csvFilePath = Export::arrayToCsvSimple($csvContent, $csvFileName, true);
10311
10312
                    if ($csvFilePath && file_exists($csvFilePath)) {
10313
                        $zip->addFile($csvFilePath, $csvFileName);
10314
                    }
10315
                }
10316
            }
10317
        }
10318
10319
        if (!$zip->close()) {
10320
            exit("Could not close the ZIP file correctly.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
10321
        }
10322
10323
        if (file_exists($tempZipFile)) {
10324
            DocumentManager::file_send_for_download($tempZipFile, true);
10325
            unlink($tempZipFile);
10326
        } else {
10327
            exit("The ZIP file was not created correctly.");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

Loading history...
10328
        }
10329
    }
10330
10331
    private static function generateSessionCourseReportData($sessionId, $courseId, $userIds): array
10332
    {
10333
        $em = Database::getManager();
10334
        $sessionRepository = $em->getRepository(Session::class);
10335
        $session = $sessionRepository->find($sessionId);
10336
10337
        if (!$session instanceof Session) {
10338
            throw new \InvalidArgumentException("Invalid session object for session ID $sessionId");
10339
        }
10340
10341
        $courseInfo = api_get_course_info_by_id($courseId);
10342
        $courseCode = $courseInfo['code'];
10343
10344
        $csvHeaders = [
10345
            get_lang('Session name'),
10346
            get_lang('Session access dates'),
10347
            get_lang('Session display dates'),
10348
            get_lang('Course name'),
10349
            get_lang('Official code'),
10350
            get_lang('First name'),
10351
            get_lang('Last name'),
10352
            get_lang('Login'),
10353
            get_lang('Training time'),
10354
            get_lang('Course progress'),
10355
            get_lang('Exercise progress'),
10356
            get_lang('Exercise average'),
10357
            get_lang('Score'),
10358
            get_lang('Score') . ' - ' . get_lang('Best attempt'),
10359
            get_lang('Student_publication'),
10360
            get_lang('Messages'),
10361
            get_lang('Classes'),
10362
            get_lang('Registration date'),
10363
            get_lang('First login in course'),
10364
            get_lang('Latest login in course'),
10365
        ];
10366
10367
        $csvData = TrackingCourseLog::getUserData(
10368
            null,
10369
            count($userIds),
10370
            null,
10371
            null,
10372
            [],
10373
            true,
10374
            true,
10375
            $courseCode,
10376
            $sessionId,
10377
            true,
10378
            $userIds
10379
        );
10380
10381
        $rawCsvContent = ChamiloSession::read('csv_content');
10382
10383
        if (empty($rawCsvContent)) {
10384
            throw new \RuntimeException("No CSV content found in session for course $courseCode and session $sessionId.");
10385
        }
10386
10387
        $csvContent = [];
10388
        foreach ($rawCsvContent as $row) {
10389
            $alignedRow = [
10390
                $row['session_name'] ?? '',
10391
                $row['session_startdate'] ?? '',
10392
                $row['session_enddate'] ?? '',
10393
                $row['course_name'] ?? '',
10394
                $row['official_code'] ?? '',
10395
                $row['firstname'] ?? '',
10396
                $row['lastname'] ?? '',
10397
                $row['username'] ?? '',
10398
                $row['time'] ?? '',
10399
                $row['average_progress'] ?? '',
10400
                $row['exercise_progress'] ?? '',
10401
                $row['exercise_average'] ?? '',
10402
                $row['student_score'] ?? '',
10403
                $row['student_score_best'] ?? '',
10404
                $row['count_assignments'] ?? '',
10405
                $row['count_messages'] ?? '',
10406
                $row['classes'] ?? '',
10407
                $row['registered_at'] ?? '',
10408
                $row['first_connection'] ?? '',
10409
                $row['last_connection'] ?? '',
10410
            ];
10411
            $csvContent[] = $alignedRow;
10412
        }
10413
10414
        return [$csvHeaders, $csvContent];
10415
    }
10416
10417
}
10418