Passed
Push — master ( 65d552...4599b6 )
by Angel Fernando Quiroz
10:41
created

SessionManager::formatSessionsAdminForGrid()   F

Complexity

Conditions 26
Paths 3846

Size

Total Lines 117
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

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

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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