Passed
Push — 1.11.x ( 30cd2d...1e0231 )
by Angel Fernando Quiroz
08:36
created

SessionManager   F

Complexity

Total Complexity 1257

Size/Duplication

Total Lines 10075
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 1257
eloc 5182
c 2
b 1
f 0
dl 0
loc 10075
rs 0.8

146 Methods

Rating   Name   Duplication   Size   Complexity  
F fetch() 0 77 14
F get_user_data_access_tracking_overview() 0 141 20
F get_session_lp_progress() 0 107 13
F get_survey_overview() 0 104 13
A __construct() 0 2 1
F create_session() 0 173 33
F formatSessionsAdminForGrid() 0 117 32
F edit_session() 0 144 25
A generateNextSessionName() 0 23 4
A sessionNameExists() 0 8 1
F getSessionsForAdmin() 0 176 29
F get_session_progress() 0 341 24
B get_count_admin() 0 109 7
A user_is_general_coach() 0 14 3
A protectSession() 0 4 2
A allowOnlyMySessions() 0 10 4
A cantEditSession() 0 19 6
A allowManageAllSessions() 0 7 3
A get_session_by_course() 0 24 2
A get_sessions_by_user() 0 24 5
A count_sessions() 0 14 2
A protect_teacher_session_edit() 0 6 3
A allowToManageSessions() 0 13 4
C subscribeSessionsToDrh() 0 106 12
A getUserStatusInSession() 0 11 1
A get_course_list_by_session_id_like() 0 33 5
A getSessionIdFromOriginalId() 0 13 2
A getCourseCountBySessionId() 0 29 3
A removeAllDrhFromSession() 0 16 2
A get_sessions_followed_by_drh() 0 24 1
A subscribe_sessions_to_promotion() 0 16 3
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
A get_user_status_in_course_session() 0 21 2
F getSessionsFollowedByUser() 0 187 33
A clear_session_ref_promotion() 0 11 2
B get_course_list_by_session_id() 0 55 8
A getDrhUsersInSession() 0 3 1
B getAllCoursesFollowedByUser() 0 71 9
A set_session_status() 0 5 1
A getSessionFollowedByDrh() 0 40 3
A get_sessions_by_general_coach() 0 33 5
F add_courses_to_session() 0 289 36
A unsubscribe_user_from_session() 0 41 3
A getUsersByCourseSession() 0 35 6
F edit_category_session() 0 58 20
A create_session_extra_field() 0 15 1
B getUsersByCourseAndSessionList() 0 40 8
B subscribe_users_to_session_course() 0 42 6
D create_category_session() 0 65 19
A unsubscribe_course_from_session() 0 46 3
B removeUsersFromCourseSession() 0 63 9
A sessionNameExistBesidesMySession() 0 20 3
B set_coach_to_course_session() 0 95 10
F get_sessions_list() 0 94 17
A get_all_session_category() 0 15 2
A unSubscribeUserFromCourseSession() 0 30 2
A get_session_by_name() 0 17 3
A get_session_category() 0 13 2
A delete_session_category() 0 38 4
F subscribeUsersToSession() 0 223 25
B getHotSessions() 0 58 6
A update_session_extra_field_value() 0 10 1
A relation_session_course_exist() 0 15 2
F delete() 0 201 15
F copy() 0 217 39
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
B 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
D setForm() 0 312 16
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 959 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

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