Passed
Push — 1.11.x ( 7c5f2d...4b0106 )
by Angel Fernando Quiroz
09:57 queued 15s
created

SessionManager   F

Complexity

Total Complexity 1284

Size/Duplication

Total Lines 10239
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 1284
eloc 5282
c 1
b 0
f 0
dl 0
loc 10239
rs 0.8

147 Methods

Rating   Name   Duplication   Size   Complexity  
F fetch() 0 77 14
A __construct() 0 2 1
A removeAllDrhFromSession() 0 16 2
A unSubscribeUserFromCourseSession() 0 30 2
F create_session() 0 173 33
A sessionNameExists() 0 8 1
B get_count_admin() 0 109 7
F add_courses_to_session() 0 289 36
C subscribeSessionsToDrh() 0 106 12
F formatSessionsAdminForGrid() 0 117 32
A getUsersByCourseSession() 0 35 6
F edit_category_session() 0 58 20
A create_session_extra_field() 0 15 1
A user_is_general_coach() 0 14 3
B getUsersByCourseAndSessionList() 0 40 8
A getUserStatusInSession() 0 11 1
F edit_session() 0 144 25
B subscribe_users_to_session_course() 0 42 6
A get_course_list_by_session_id_like() 0 33 5
A protectSession() 0 4 2
A generateNextSessionName() 0 23 4
A getSessionIdFromOriginalId() 0 13 2
D create_category_session() 0 65 19
A getCourseCountBySessionId() 0 29 3
A allowOnlyMySessions() 0 10 4
A unsubscribe_course_from_session() 0 46 3
A cantEditSession() 0 19 6
B removeUsersFromCourseSession() 0 63 9
A sessionNameExistBesidesMySession() 0 20 3
F get_user_data_access_tracking_overview() 0 141 20
A get_sessions_followed_by_drh() 0 24 1
B set_coach_to_course_session() 0 95 10
F get_sessions_list() 0 94 17
A subscribe_sessions_to_promotion() 0 16 3
A get_all_session_category() 0 15 2
F get_session_lp_progress() 0 107 13
B get_users_by_session() 0 60 9
A get_sessions_by_coach() 0 8 1
A get_all_sessions_by_promotion() 0 8 1
F get_survey_overview() 0 104 13
A get_session_by_name() 0 17 3
A get_user_status_in_course_session() 0 21 2
F getSessionsFollowedByUser() 0 187 33
A clear_session_ref_promotion() 0 11 2
F getSessionsForAdmin() 0 180 32
A allowManageAllSessions() 0 7 3
B get_course_list_by_session_id() 0 55 8
A get_session_category() 0 13 2
A getDrhUsersInSession() 0 3 1
F delete() 0 201 15
A delete_session_category() 0 38 4
F get_session_progress() 0 341 24
B getAllCoursesFollowedByUser() 0 71 9
B getHotSessions() 0 58 6
A set_session_status() 0 5 1
A getSessionFollowedByDrh() 0 40 3
A update_session_extra_field_value() 0 10 1
A count_sessions() 0 14 2
F copy() 0 217 39
A protect_teacher_session_edit() 0 6 3
A get_sessions_by_general_coach() 0 33 5
A relation_session_course_exist() 0 15 2
A allowToManageSessions() 0 13 4
B get_session_by_course() 0 34 6
A get_sessions_by_user() 0 24 5
A unsubscribe_user_from_session() 0 45 4
F subscribeUsersToSession() 0 227 26
B getSessionsCoachedByUser() 0 47 10
A addFlashSessionReadOnly() 0 5 3
A getCoachesBySession() 0 18 3
B getSessionCategoryIdByName() 0 36 7
A getDefaultSessionTab() 0 10 2
A getSessionListTabs() 0 41 5
A getStatusList() 0 7 1
A compareArraysToMerge() 0 15 6
A searchSession() 0 36 4
A getUserSession() 0 19 4
A addClassesByName() 0 24 5
A getAvoidedCoursesInSession() 0 17 3
C getShortSessionListAndExtraByCategory() 0 96 13
B convertSessionDateToString() 0 42 7
B getCareersFromSession() 0 27 7
F getGridColumns() 0 393 18
B getCollapsableData() 0 33 7
C getTeacherTracking() 0 83 14
A getDescriptionFromSessionId() 0 26 3
A getSessionCourseForUser() 0 23 5
F getAllUsersFromCoursesFromAllSessionFromStatus() 0 225 31
A getAllCoursesFromAllSessionFromDrh() 0 14 4
B move() 0 62 9
A getDayLeftInSession() 0 27 3
A getSessionVisibility() 0 9 4
A getPath() 0 17 4
A getCoursesListByCourseCoach() 0 10 1
A isValidId() 0 15 3
A getTotalUserCoursesInSession() 0 38 4
A getSessionsFollowedForGroupAdmin() 0 45 5
A getCoachesByCourseSessionToString() 0 19 5
A moveDown() 0 3 1
A sessionHasCourse() 0 25 3
B copyStudentsFromSession() 0 63 8
C getSessionListAndExtraByCategoryId() 0 127 15
A getStatusLabel() 0 9 2
A insertUsersInCourses() 0 23 3
B getCountUserTracking() 0 71 7
A parseSessionDates() 0 29 1
A getCoursesForCourseSessionCoach() 0 27 4
C importSessionDrhCSV() 0 49 12
B updateCoaches() 0 28 7
C convert_dates_to_local() 0 41 11
A getCountUsersInCourseSession() 0 26 1
A getCourseToolToBeManaged() 0 5 1
A redirectToSession() 0 18 5
A compareBySessionName() 0 12 5
A isUserSubscribedAsStudent() 0 21 3
A moveUp() 0 3 1
A getCoursesInSession() 0 23 3
F get_sessions_admin_complete() 0 257 35
A compareByCourse() 0 8 3
A durationPerUserIsEnabled() 0 3 1
B checkSubscribeDrhToSessionList() 0 41 11
A getTotalUserTimeInPlatform() 0 27 5
F setForm() 0 327 20
A getAdminPath() 0 9 2
B copyCoachesFromSessionToCourse() 0 60 10
A getCoursesForMainSessionCoach() 0 25 5
B allowed() 0 31 9
A compareCatSessionInfo() 0 8 3
A editUserSessionDuration() 0 16 3
A isSessionFollowedByDrh() 0 31 2
A getCoachesByCourseSession() 0 21 3
A installCourse() 0 9 3
F importCSV() 0 961 184
B getNamedSessionCourseForCoach() 0 75 8
A subscribeDrhToSessionList() 0 17 4
C get_count_admin_complete() 0 99 10
A importAgendaFromSessionModel() 0 36 2
A searchCourseInSessionsFromUser() 0 14 3
A unInstallCourse() 0 9 3
C insertUsersInCourse() 0 102 13
B getFilteredExtraFields() 0 48 8
A compareByUserCourseCat() 0 8 3
A isUserSubscribedAsHRM() 0 22 3
A getAllCoursesFromAllSessions() 0 14 4
A orderCourseIsEnabled() 0 8 2
B getCareerDiagramPerSessionList() 0 55 10
C exportCourseSessionReport() 0 115 14

How to fix   Complexity   

Complex Class

Complex classes like SessionManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SessionManager, and based on these observations, apply Extract Interface, too.

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

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

Loading history...
10157
        }
10158
10159
        $config = api_get_configuration_value('session_course_excel_export');
10160
        $sessionFields = $config['session_fields'] ?? [];
10161
        $userFieldsBefore = $config['user_fields_before'] ?? [];
10162
        $userFieldsAfter = $config['user_fields_after'] ?? [];
10163
10164
        // 1. SESSION HEADER
10165
        $header1 = [''];
10166
        $header1[] = get_lang('StartDate');
10167
        $header1[] = get_lang('EndDate');
10168
10169
        $extraField = new ExtraFieldModel('session');
10170
        $extraDefs = $extraField->get_all();
10171
        $extraDefsByVariable = array_column($extraDefs, null, 'variable');
10172
10173
        foreach ($sessionFields as $field) {
10174
            if (isset($extraDefsByVariable[$field])) {
10175
                $header1[] = $extraDefsByVariable[$field]['display_text'] ?? strtoupper($field);
10176
            }
10177
        }
10178
10179
        // 2. SESSION DATA
10180
        $row2 = [$courseInfo['title']];
10181
        $row2[] = $sessionInfo['access_start_date'];
10182
        $row2[] = $sessionInfo['access_end_date'];
10183
10184
        $extraValuesObj = new ExtraFieldValue('session');
10185
        $sessionExtra = $extraValuesObj->getAllValuesByItem($sessionId);
10186
        $sessionExtraMap = array_column($sessionExtra, 'value', 'variable');
10187
10188
        foreach ($sessionFields as $field) {
10189
            $value = $sessionExtraMap[$field] ?? '';
10190
            $row2[] = $value;
10191
        }
10192
10193
        // 3. USER HEADER
10194
        $header3 = [''];
10195
        foreach ($userFieldsBefore as $field) {
10196
            $header3[] = strtoupper($field);
10197
        }
10198
        $header3[] = get_lang('FirstName');
10199
        $header3[] = get_lang('LastName');
10200
        $header3[] = get_lang('OfficialCode');
10201
        foreach ($userFieldsAfter as $field) {
10202
            $header3[] = strtoupper($field);
10203
        }
10204
10205
        // 4. USERS WITH CERTIFICATE
10206
        $dataRows = [];
10207
10208
        $tblCat = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
10209
        $sql = "
10210
            SELECT id FROM $tblCat
10211
            WHERE course_code = '".Database::escape_string($courseCode)."'
10212
            AND session_id = ".intval($sessionId)."
10213
            AND generate_certificates = 1
10214
            LIMIT 1
10215
        ";
10216
        $res = Database::query($sql);
10217
        $row = Database::fetch_array($res);
10218
        $catId = $row ? (int) $row['id'] : 0;
10219
10220
        if ($catId > 0) {
10221
            $tableCertificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
10222
            $sql = "SELECT DISTINCT user_id FROM $tableCertificate WHERE cat_id = $catId";
10223
            $res = Database::query($sql);
10224
10225
            $rowIndex = 0;
10226
            while ($cert = Database::fetch_array($res)) {
10227
                $userId = $cert['user_id'];
10228
                $userInfo = api_get_user_info($userId);
10229
10230
                $row = [];
10231
                $row[] = $rowIndex === 0 ? get_lang('Learners') : '';
10232
10233
                $userExtraObj = new ExtraFieldValue('user');
10234
                $userExtra = $userExtraObj->getAllValuesByItem($userId);
10235
                $userExtraMap = array_column($userExtra, 'value', 'variable');
10236
10237
                foreach ($userFieldsBefore as $field) {
10238
                    $value = $userExtraMap[$field] ?? '';
10239
                    $row[] = $value;
10240
                }
10241
10242
                $row[] = $userInfo['firstname'];
10243
                $row[] = $userInfo['lastname'];
10244
                $row[] = $userInfo['official_code'] ?? '';
10245
10246
                foreach ($userFieldsAfter as $field) {
10247
                    $value = $userExtraMap[$field] ?? '';
10248
                    $row[] = $value;
10249
                }
10250
10251
                $dataRows[] = $row;
10252
                $rowIndex++;
10253
            }
10254
        }
10255
10256
        // 5. EXPORT FINAL
10257
        $rows = [];
10258
        $rows[] = $header1;
10259
        $rows[] = $row2;
10260
        $rows[] = $header3;
10261
        $rows = array_merge($rows, $dataRows);
10262
10263
        $filename = 'session_'.$sessionId.'_course_'.$courseCode;
10264
        Export::arrayToXls($rows, $filename);
10265
    }
10266
}
10267