Passed
Push — master ( 96ed0e...2e6c00 )
by
unknown
14:08 queued 07:15
created

SessionManager   F

Complexity

Total Complexity 1274

Size/Duplication

Total Lines 10103
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5174
c 1
b 0
f 0
dl 0
loc 10103
rs 0.8
wmc 1274

152 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
B fetch() 0 54 7
F create_session() 0 174 32
F formatSessionsAdminForGrid() 0 117 26
A unsubscribe_user_from_session() 0 39 3
A getCountUsersLangBySession() 0 38 5
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
F edit_session() 0 158 28
B subscribe_users_to_session_course() 0 47 7
A generateNextSessionName() 0 23 4
D create_category_session() 0 65 19
A unsubscribe_course_from_session() 0 43 4
B removeUsersFromCourseSession() 0 63 9
A sessionNameExistBesidesMySession() 0 20 3
F get_user_data_access_tracking_overview() 0 141 20
F get_sessions_list() 0 91 17
A get_all_session_category() 0 15 2
F get_session_lp_progress() 0 107 13
A sessionNameExists() 0 8 1
A unSubscribeUserFromCourseSession() 0 30 2
F get_survey_overview() 0 98 13
A get_session_by_name() 0 17 3
A clear_session_ref_promotion() 0 11 2
F getSessionsForAdmin() 0 326 60
A get_session_category() 0 13 2
C delete() 0 116 11
A delete_session_category() 0 38 4
F get_session_progress() 0 347 24
F subscribeUsersToSession() 0 205 23
B get_count_admin() 0 110 8
B getHotSessions() 0 53 6
A update_session_extra_field_value() 0 10 1
A relation_session_course_exist() 0 15 2
F add_courses_to_session() 0 272 28
B getSessionsCoachedByUser() 0 47 10
A getSessionChangeUserReasons() 0 6 1
C subscribeSessionsToDrh() 0 85 12
A addFlashSessionReadOnly() 0 5 3
A getCoachesBySession() 0 18 3
B getSessionCategoryIdByName() 0 36 7
A getDefaultSessionTab() 0 10 3
A getSessionListTabs() 0 41 5
A getStatusList() 0 7 1
A getGeneralCoachesIdForSession() 0 6 1
A compareArraysToMerge() 0 15 6
A getUserStatusInSession() 0 11 1
A searchSession() 0 36 4
A getUserSession() 0 19 4
A get_course_list_by_session_id_like() 0 33 5
A addClassesByName() 0 17 4
A getSessionChangeUserReason() 0 5 1
A getAvoidedCoursesInSession() 0 17 3
A protectSession() 0 4 2
C getShortSessionListAndExtraByCategory() 0 96 13
B convertSessionDateToString() 0 42 7
A getSessionIdFromOriginalId() 0 13 2
B getCareersFromSession() 0 28 7
F getGridColumns() 0 458 19
A getCourseCountBySessionId() 0 29 3
A allowOnlyMySessions() 0 10 4
A cantEditSession() 0 19 6
A get_sessions_followed_by_drh() 0 24 1
B set_coach_to_course_session() 0 92 10
A getSessionPictureUrl() 0 6 1
B getCollapsableData() 0 33 7
C getTeacherTracking() 0 83 14
A subscribe_sessions_to_promotion() 0 16 3
A getDescriptionFromSessionId() 0 26 3
A getSessionCourseForUser() 0 23 5
F getAllUsersFromCoursesFromAllSessionFromStatus() 0 216 28
A getAllCoursesFromAllSessionFromDrh() 0 14 4
B move() 0 62 9
A getDayLeftInSession() 0 27 3
B get_users_by_session() 0 60 9
A getSessionVisibility() 0 12 4
A getPath() 0 17 4
A get_all_sessions_by_promotion() 0 8 1
A getCoursesListByCourseCoach() 0 8 1
A isValidId() 0 15 3
A getTotalUserCoursesInSession() 0 38 4
A getSessionsFollowedForGroupAdmin() 0 45 5
A getCoachesByCourseSessionToString() 0 19 5
A getGeneralCoachesNamesForSession() 0 6 1
A moveDown() 0 3 1
A sessionHasCourse() 0 25 3
B copyStudentsFromSession() 0 63 8
A get_user_status_in_course_session() 0 21 2
C getSessionListAndExtraByCategoryId() 0 127 15
F getSessionsFollowedByUser() 0 182 33
A getStatusLabel() 0 9 2
A insertUsersInCourses() 0 12 3
A getCountUserTracking() 0 51 5
A parseSessionDates() 0 26 1
A getCoursesForCourseSessionCoach() 0 27 4
C importSessionDrhCSV() 0 48 12
B updateCoaches() 0 28 7
C convert_dates_to_local() 0 41 11
A getCountUsersInCourseSession() 0 26 1
A getCourseToolToBeManaged() 0 5 1
A deleteAsset() 0 11 2
A redirectToSession() 0 18 5
A compareBySessionName() 0 12 5
A allowManageAllSessions() 0 7 3
A isUserSubscribedAsStudent() 0 21 3
B get_course_list_by_session_id() 0 55 8
A getDrhUsersInSession() 0 3 1
A moveUp() 0 3 1
A get_session_by_course() 0 24 2
A getCoursesInSession() 0 23 3
F get_sessions_admin_complete() 0 252 35
A compareByCourse() 0 8 3
A durationPerUserIsEnabled() 0 3 1
B checkSubscribeDrhToSessionList() 0 41 11
B getAllCoursesFollowedByUser() 0 71 9
A getTotalUserTimeInPlatform() 0 27 5
A get_sessions_by_user() 0 24 5
F setForm() 0 315 19
B getAllUserIdsInSession() 0 31 8
A getAdminPath() 0 9 2
B copyCoachesFromSessionToCourse() 0 60 10
A getCoursesForMainSessionCoach() 0 22 5
B allowed() 0 30 9
A compareCatSessionInfo() 0 8 3
A editUserSessionDuration() 0 16 3
A set_session_status() 0 5 1
A isSessionFollowedByDrh() 0 31 2
A getCoachesByCourseSession() 0 21 3
A installCourse() 0 9 3
A updateSessionPicture() 0 25 3
A getSessionFollowedByDrh() 0 40 3
F importCSV() 0 1014 191
B getNamedSessionCourseForCoach() 0 59 7
A subscribeDrhToSessionList() 0 17 4
A count_sessions() 0 14 2
F copy() 0 212 35
C get_count_admin_complete() 0 105 10
A sessionHasSessionAdmin() 0 8 1
A searchCourseInSessionsFromUser() 0 14 3
A unInstallCourse() 0 9 3
A insertUsersInCourse() 0 31 4
B getFilteredExtraFields() 0 58 10
A protect_teacher_session_edit() 0 6 3
A compareByUserCourseCat() 0 8 3
A isUserSubscribedAsHRM() 0 22 3
A get_sessions_by_general_coach() 0 31 5
A getAllCoursesFromAllSessions() 0 14 4
A orderCourseIsEnabled() 0 8 2
B getCareerDiagramPerSessionList() 0 43 8
A allowToManageSessions() 0 11 4

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