Passed
Push — 1.11.x ( 4f13a8...3330b3 )
by Angel Fernando Quiroz
13:55 queued 13s
created

Rest   F

Complexity

Total Complexity 317

Size/Duplication

Total Lines 2388
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 1295
c 5
b 0
f 0
dl 0
loc 2388
rs 0.8
wmc 317

58 Methods

Rating   Name   Duplication   Size   Complexity  
A decodeParams() 0 3 1
A init() 0 11 2
A validate() 0 9 2
A __construct() 0 3 1
A getCourseAgenda() 0 51 4
A getCoursesCampus() 0 13 1
A getUserReceivedMessages() 0 33 3
A addCoursesSession() 0 25 3
A setCourse() 0 25 3
A getUsersCampus() 0 19 2
A deleteUserMessage() 0 6 2
A setMessageRead() 0 3 1
A showLearningPath() 0 25 2
A getUsersSubscribedToCourse() 0 16 2
D addUser() 0 111 13
A getUserSentMessages() 0 27 2
F updateSession() 0 141 36
A getUserProfile() 0 28 2
A getUserCourses() 0 36 4
A usernameExist() 0 3 1
A getCourseForum() 0 36 5
A saveForumThread() 0 13 2
A getLegalConditions() 0 25 3
A updateConditionAccepted() 0 16 3
A getCourseNotebooks() 0 24 1
A encodeParams() 0 11 1
C getCourseLearnPaths() 0 110 17
A getMessageUsers() 0 23 3
A getSessionFromExtraField() 0 24 3
A setSession() 0 23 3
D createSessionFromModel() 0 91 20
A getCourseQuizMdlCompat() 0 48 2
A saveCourseNotebook() 0 16 2
A saveUserMessage() 0 8 2
A subscribeUserToSessionFromUsername() 0 22 4
A getUserMessages() 0 26 2
A getCourseAnnouncement() 0 28 3
A getCourseForumThread() 0 32 3
A getCourseInfo() 0 21 2
A saveForumPost() 0 11 1
A addSession() 0 47 3
A checkConditionalLogin() 0 29 6
A getCourseDescriptions() 0 19 2
A getCourseLpProgress() 0 11 2
A setGcmId() 0 10 1
A getUserSessions() 0 48 5
A addUsersSession() 0 19 2
A createCampusURL() 0 25 4
F addCourse() 0 52 14
B getCourseForumCategories() 0 66 8
F updateUserFromUserName() 0 187 69
A unSubscribeUserToCourse() 0 19 5
A editCampusURL() 0 24 6
B getCourseDocuments() 0 73 8
A deleteCampusURL() 0 14 3
A getCourseAnnouncements() 0 34 2
A subscribeUserToCourse() 0 19 5
A logout() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like Rest 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 Rest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Course;
6
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
7
use Chamilo\CoreBundle\Entity\Session;
8
use Chamilo\CourseBundle\Entity\CLpCategory;
9
use Chamilo\CourseBundle\Entity\CNotebook;
10
use Chamilo\CourseBundle\Entity\Repository\CNotebookRepository;
11
use Chamilo\UserBundle\Entity\User;
12
13
/**
14
 * Class RestApi.
15
 */
16
class Rest extends WebService
17
{
18
    const SERVICE_NAME = 'MsgREST';
19
    const EXTRA_FIELD_GCM_REGISTRATION = 'gcm_registration_id';
20
21
    const GET_AUTH = 'authenticate';
22
    const GET_USER_MESSAGES = 'user_messages';
23
    const GET_USER_COURSES = 'user_courses';
24
    const GET_USER_SESSIONS = 'user_sessions';
25
    const GET_USERS_SUBSCRIBED_TO_COURSE = 'get_users_subscribed_to_course';
26
    const GET_USER_MESSAGES_RECEIVED = 'user_messages_received';
27
    const GET_USER_MESSAGES_SENT = 'user_messages_sent';
28
    const POST_USER_MESSAGE_READ = 'user_message_read';
29
    const POST_USER_MESSAGE_UNREAD = 'user_message_unread';
30
    const SAVE_GCM_ID = 'gcm_id';
31
    const GET_PROFILE = 'user_profile';
32
    const GET_COURSE_INFO = 'course_info';
33
    const GET_COURSE_DESCRIPTIONS = 'course_descriptions';
34
    const GET_COURSE_DOCUMENTS = 'course_documents';
35
    const GET_COURSE_ANNOUNCEMENTS = 'course_announcements';
36
    const GET_COURSE_ANNOUNCEMENT = 'course_announcement';
37
    const GET_COURSE_AGENDA = 'course_agenda';
38
    const GET_COURSE_NOTEBOOKS = 'course_notebooks';
39
    const GET_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
40
    const GET_COURSE_FORUM = 'course_forum';
41
    const GET_COURSE_FORUM_THREAD = 'course_forumthread';
42
    const GET_COURSE_LEARNPATHS = 'course_learnpaths';
43
    const GET_COURSE_LEARNPATH = 'course_learnpath';
44
    const GET_COURSE_LP_PROGRESS = 'course_lp_progress';
45
    const SAVE_FORUM_POST = 'save_forum_post';
46
    const SAVE_USER_MESSAGE = 'save_user_message';
47
    const GET_MESSAGE_USERS = 'message_users';
48
    const SAVE_COURSE_NOTEBOOK = 'save_course_notebook';
49
    const SAVE_FORUM_THREAD = 'save_forum_thread';
50
    const SAVE_COURSE = 'save_course';
51
    const SAVE_USER = 'save_user';
52
    const SAVE_USER_JSON = 'save_user_json';
53
    const SUBSCRIBE_USER_TO_COURSE = 'subscribe_user_to_course';
54
    const UNSUBSCRIBE_USER_FROM_COURSE = 'unsubscribe_user_from_course';
55
    const EXTRAFIELD_GCM_ID = 'gcm_registration_id';
56
    const DELETE_USER_MESSAGE = 'delete_user_message';
57
    const SET_MESSAGE_READ = 'set_message_read';
58
    const CREATE_CAMPUS = 'add_campus';
59
    const EDIT_CAMPUS = 'edit_campus';
60
    const DELETE_CAMPUS = 'delete_campus';
61
    const SAVE_SESSION = 'save_session';
62
    const UPDATE_SESSION = 'update_session';
63
    const GET_USERS = 'get_users';
64
    const GET_COURSES = 'get_courses';
65
    const GET_COURSES_FROM_EXTRA_FIELD = 'get_courses_from_extra_field';
66
    const ADD_COURSES_SESSION = 'add_courses_session';
67
    const ADD_USERS_SESSION = 'add_users_session';
68
    const CREATE_SESSION_FROM_MODEL = 'create_session_from_model';
69
    const SUBSCRIBE_USER_TO_SESSION_FROM_USERNAME = 'subscribe_user_to_session_from_username';
70
    const GET_SESSION_FROM_EXTRA_FIELD = 'get_session_from_extra_field';
71
    const UPDATE_USER_FROM_USERNAME = 'update_user_from_username';
72
    const USERNAME_EXIST = 'username_exist';
73
    const GET_COURSE_QUIZ_MDL_COMPAT = 'get_course_quiz_mdl_compat';
74
    const UPDATE_USER_PAUSE_TRAINING = 'update_user_pause_training';
75
    const DELETE_COURSE = 'delete_course';
76
    const CHECK_CONDITIONAL_LOGIN = 'check_conditional_login';
77
    const GET_LEGAL_CONDITIONS = 'get_legal_conditions';
78
    const UPDATE_CONDITION_ACCEPTED = 'update_condition_accepted';
79
    const LOGOUT = 'logout';
80
81
    /**
82
     * @var Session
83
     */
84
    private $session;
85
86
    /**
87
     * @var Course
88
     */
89
    private $course;
90
91
    /**
92
     * Rest constructor.
93
     *
94
     * @param string $username
95
     * @param string $apiKey
96
     */
97
    public function __construct($username, $apiKey)
98
    {
99
        parent::__construct($username, $apiKey);
100
    }
101
102
    /**
103
     * @param string $username
104
     * @param string $apiKeyToValidate
105
     *
106
     * @throws Exception
107
     *
108
     * @return Rest
109
     */
110
    public static function validate($username, $apiKeyToValidate)
111
    {
112
        $apiKey = self::findUserApiKey($username, self::SERVICE_NAME);
113
114
        if ($apiKey != $apiKeyToValidate) {
115
            throw new Exception(get_lang('InvalidApiKey'));
116
        }
117
118
        return new self($username, $apiKey);
119
    }
120
121
    /**
122
     * Create the gcm_registration_id extra field for users.
123
     */
124
    public static function init()
125
    {
126
        $extraField = new ExtraField('user');
127
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
128
129
        if (empty($fieldInfo)) {
130
            $extraField->save(
131
                [
132
                    'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
133
                    'field_type' => ExtraField::FIELD_TYPE_TEXT,
134
                    'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION,
135
                ]
136
            );
137
        }
138
    }
139
140
    /**
141
     * @param string $encoded
142
     *
143
     * @return array
144
     */
145
    public static function decodeParams($encoded)
146
    {
147
        return json_decode($encoded);
148
    }
149
150
    /**
151
     * Set the current course.
152
     *
153
     * @param int $id
154
     *
155
     * @throws Exception
156
     */
157
    public function setCourse($id)
158
    {
159
        if (!$id) {
160
            $this->course = null;
161
162
            ChamiloSession::erase('_real_cid');
163
            ChamiloSession::erase('_cid');
164
            ChamiloSession::erase('_course');
165
166
            return;
167
        }
168
169
        $em = Database::getManager();
170
        /** @var Course $course */
171
        $course = $em->find('ChamiloCoreBundle:Course', $id);
172
173
        if (!$course) {
0 ignored issues
show
introduced by
$course is of type Chamilo\CoreBundle\Entity\Course, thus it always evaluated to true.
Loading history...
174
            throw new Exception(get_lang('NoCourse'));
175
        }
176
177
        $this->course = $course;
178
179
        ChamiloSession::write('_real_cid', $course->getId());
180
        ChamiloSession::write('_cid', $course->getCode());
181
        ChamiloSession::write('_course', api_get_course_info($course->getCode()));
182
    }
183
184
    /**
185
     * Set the current session.
186
     *
187
     * @param int $id
188
     *
189
     * @throws Exception
190
     */
191
    public function setSession($id)
192
    {
193
        if (!$id) {
194
            $this->session = null;
195
196
            ChamiloSession::erase('session_name');
197
            ChamiloSession::erase('id_session');
198
199
            return;
200
        }
201
202
        $em = Database::getManager();
203
        /** @var Session $session */
204
        $session = $em->find('ChamiloCoreBundle:Session', $id);
205
206
        if (!$session) {
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
207
            throw new Exception(get_lang('NoSession'));
208
        }
209
210
        $this->session = $session;
211
212
        ChamiloSession::write('session_name', $session->getName());
213
        ChamiloSession::write('id_session', $session->getId());
214
    }
215
216
    /**
217
     * @param string $registrationId
218
     *
219
     * @return bool
220
     */
221
    public function setGcmId($registrationId)
222
    {
223
        $registrationId = Security::remove_XSS($registrationId);
224
        $extraFieldValue = new ExtraFieldValue('user');
225
226
        return $extraFieldValue->save(
227
            [
228
                'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
229
                'value' => $registrationId,
230
                'item_id' => $this->user->getId(),
231
            ]
232
        );
233
    }
234
235
    /**
236
     * @param int $lastMessageId
237
     *
238
     * @return array
239
     */
240
    public function getUserMessages($lastMessageId = 0)
241
    {
242
        $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
243
        $messages = [];
244
245
        foreach ($lastMessages as $message) {
246
            $hasAttachments = MessageManager::hasAttachments($message['id']);
247
248
            $messages[] = [
249
                'id' => $message['id'],
250
                'title' => $message['title'],
251
                'sender' => [
252
                    'id' => $message['user_id'],
253
                    'lastname' => $message['lastname'],
254
                    'firstname' => $message['firstname'],
255
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
256
                ],
257
                'sendDate' => $message['send_date'],
258
                'content' => $message['content'],
259
                'hasAttachments' => $hasAttachments,
260
                'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?'
261
                    .http_build_query(['type' => 1, 'id' => $message['id']]),
262
            ];
263
        }
264
265
        return $messages;
266
    }
267
268
    /**
269
     * @return array
270
     */
271
    public function getUserReceivedMessages()
272
    {
273
        $lastMessages = MessageManager::getReceivedMessages($this->user->getId(), 0);
274
        $messages = [];
275
276
        $webPath = api_get_path(WEB_PATH);
277
278
        foreach ($lastMessages as $message) {
279
            $hasAttachments = MessageManager::hasAttachments($message['id']);
280
            $attachmentList = [];
281
            if ($hasAttachments) {
282
                $attachmentList = MessageManager::getAttachmentList($message['id']);
283
            }
284
            $messages[] = [
285
                'id' => $message['id'],
286
                'title' => $message['title'],
287
                'msgStatus' => $message['msg_status'],
288
                'sender' => [
289
                    'id' => $message['user_id'],
290
                    'lastname' => $message['lastname'],
291
                    'firstname' => $message['firstname'],
292
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
293
                    'pictureUri' => $message['pictureUri'],
294
                ],
295
                'sendDate' => $message['send_date'],
296
                'content' => str_replace('src="/"', $webPath, $message['content']),
297
                'hasAttachments' => $hasAttachments,
298
                'attachmentList' => $attachmentList,
299
                'url' => '',
300
            ];
301
        }
302
303
        return $messages;
304
    }
305
306
    /**
307
     * @return array
308
     */
309
    public function getUserSentMessages()
310
    {
311
        $lastMessages = MessageManager::getSentMessages($this->user->getId(), 0);
312
        $messages = [];
313
314
        foreach ($lastMessages as $message) {
315
            $hasAttachments = MessageManager::hasAttachments($message['id']);
316
317
            $messages[] = [
318
                'id' => $message['id'],
319
                'title' => $message['title'],
320
                'msgStatus' => $message['msg_status'],
321
                'receiver' => [
322
                    'id' => $message['user_id'],
323
                    'lastname' => $message['lastname'],
324
                    'firstname' => $message['firstname'],
325
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
326
                    'pictureUri' => $message['pictureUri'],
327
                ],
328
                'sendDate' => $message['send_date'],
329
                'content' => $message['content'],
330
                'hasAttachments' => $hasAttachments,
331
                'url' => '',
332
            ];
333
        }
334
335
        return $messages;
336
    }
337
338
    /**
339
     * Get the user courses.
340
     */
341
    public function getUserCourses($userId = 0): array
342
    {
343
        if (empty($userId)) {
344
            $userId = $this->user->getId();
345
        }
346
347
        Event::courseLogout(
348
            [
349
                'uid' => $userId,
350
                'cid' => api_get_course_id(),
351
                'sid' => api_get_session_id(),
352
            ]
353
        );
354
355
        $courses = CourseManager::get_courses_list_by_user_id($userId);
356
        $data = [];
357
358
        foreach ($courses as $courseInfo) {
359
            /** @var Course $course */
360
            $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseInfo['real_id']);
361
            $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode());
362
            $picturePath = CourseManager::getPicturePath($course, true)
363
                ?: Display::return_icon('session_default.png', null, null, null, null, true);
364
365
            $data[] = [
366
                'id' => $course->getId(),
367
                'title' => $course->getTitle(),
368
                'code' => $course->getCode(),
369
                'directory' => $course->getDirectory(),
370
                'urlPicture' => $picturePath,
371
                'teachers' => $teachers,
372
                'isSpecial' => !empty($courseInfo['special_course']),
373
            ];
374
        }
375
376
        return $data;
377
    }
378
379
    /**
380
     * @throws Exception
381
     *
382
     * @return array
383
     */
384
    public function getCourseInfo()
385
    {
386
        $teachers = CourseManager::getTeacherListFromCourseCodeToString($this->course->getCode());
387
        $tools = CourseHome::get_tools_category(
388
            TOOL_STUDENT_VIEW,
389
            $this->course->getId(),
390
            $this->session ? $this->session->getId() : 0
391
        );
392
393
        return [
394
            'id' => $this->course->getId(),
395
            'title' => $this->course->getTitle(),
396
            'code' => $this->course->getCode(),
397
            'directory' => $this->course->getDirectory(),
398
            'urlPicture' => CourseManager::getPicturePath($this->course, true),
399
            'teachers' => $teachers,
400
            'tools' => array_map(
401
                function ($tool) {
402
                    return ['type' => $tool['name']];
403
                },
404
                $tools
405
            ),
406
        ];
407
    }
408
409
    /**
410
     * Get the course descriptions.
411
     *
412
     * @throws Exception
413
     *
414
     * @return array
415
     */
416
    public function getCourseDescriptions()
417
    {
418
        Event::event_access_tool(TOOL_COURSE_DESCRIPTION);
419
420
        $descriptions = CourseDescription::get_descriptions($this->course->getId());
421
        $results = [];
422
423
        $webPath = api_get_path(WEB_PATH);
424
425
        /** @var CourseDescription $description */
426
        foreach ($descriptions as $description) {
427
            $results[] = [
428
                'id' => $description->get_description_type(),
429
                'title' => $description->get_title(),
430
                'content' => str_replace('src="/', 'src="'.$webPath, $description->get_content()),
431
            ];
432
        }
433
434
        return $results;
435
    }
436
437
    /**
438
     * @param int $directoryId
439
     *
440
     * @throws Exception
441
     *
442
     * @return array
443
     */
444
    public function getCourseDocuments($directoryId = 0)
445
    {
446
        Event::event_access_tool(TOOL_DOCUMENT);
447
448
        /** @var string $path */
449
        $path = '/';
450
        $sessionId = $this->session ? $this->session->getId() : 0;
451
452
        if ($directoryId) {
453
            $directory = DocumentManager::get_document_data_by_id(
454
                $directoryId,
455
                $this->course->getCode(),
456
                false,
457
                $sessionId
458
            );
459
460
            if (!$directory) {
461
                throw new Exception('NoDataAvailable');
462
            }
463
464
            $path = $directory['path'];
465
        }
466
467
        $courseInfo = api_get_course_info_by_id($this->course->getId());
468
        $documents = DocumentManager::getAllDocumentData(
469
            $courseInfo,
470
            $path,
471
            0,
472
            null,
473
            false,
474
            false,
475
            $sessionId
476
        );
477
        $results = [];
478
479
        if (!empty($documents)) {
480
            $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
481
482
            /** @var array $document */
483
            foreach ($documents as $document) {
484
                if ($document['visibility'] != '1') {
485
                    continue;
486
                }
487
488
                $icon = $document['filetype'] == 'file'
489
                    ? choose_image($document['path'])
490
                    : chooseFolderIcon($document['path']);
491
492
                $results[] = [
493
                    'id' => $document['id'],
494
                    'type' => $document['filetype'],
495
                    'title' => $document['title'],
496
                    'path' => $document['path'],
497
                    'url' => $webPath.http_build_query(
498
                        [
499
                            'username' => $this->user->getUsername(),
500
                            'api_key' => $this->apiKey,
501
                            'cidReq' => $this->course->getCode(),
502
                            'id_session' => $sessionId,
503
                            'gidReq' => 0,
504
                            'gradebook' => 0,
505
                            'origin' => '',
506
                            'action' => 'download',
507
                            'id' => $document['id'],
508
                        ]
509
                    ),
510
                    'icon' => $icon,
511
                    'size' => format_file_size($document['size']),
512
                ];
513
            }
514
        }
515
516
        return $results;
517
    }
518
519
    /**
520
     * @throws Exception
521
     *
522
     * @return array
523
     */
524
    public function getCourseAnnouncements()
525
    {
526
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
527
528
        $sessionId = $this->session ? $this->session->getId() : 0;
529
530
        $announcements = AnnouncementManager::getAnnouncements(
531
            null,
532
            null,
533
            false,
534
            null,
535
            null,
536
            null,
537
            null,
538
            null,
539
            0,
540
            $this->user->getId(),
541
            $this->course->getId(),
542
            $sessionId
543
        );
544
545
        $announcements = array_map(
546
            function ($announcement) {
547
                return [
548
                    'id' => (int) $announcement['id'],
549
                    'title' => strip_tags($announcement['title']),
550
                    'creatorName' => strip_tags($announcement['username']),
551
                    'date' => strip_tags($announcement['insert_date']),
552
                ];
553
            },
554
            $announcements
555
        );
556
557
        return $announcements;
558
    }
559
560
    /**
561
     * @param int $announcementId
562
     *
563
     * @throws Exception
564
     *
565
     * @return array
566
     */
567
    public function getCourseAnnouncement($announcementId)
568
    {
569
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
570
571
        $sessionId = $this->session ? $this->session->getId() : 0;
572
        $announcement = AnnouncementManager::getAnnouncementInfoById(
573
            $announcementId,
574
            $this->course->getId(),
575
            $this->user->getId()
576
        );
577
578
        if (!$announcement) {
579
            throw new Exception(get_lang('NoAnnouncement'));
580
        }
581
582
        return [
583
            'id' => $announcement['announcement']->getIid(),
584
            'title' => $announcement['announcement']->getTitle(),
585
            'creatorName' => UserManager::formatUserFullName($announcement['item_property']->getInsertUser()),
586
            'date' => api_convert_and_format_date(
587
                $announcement['item_property']->getInsertDate(),
588
                DATE_TIME_FORMAT_LONG_24H
589
            ),
590
            'content' => AnnouncementManager::parseContent(
591
                $this->user->getId(),
592
                $announcement['announcement']->getContent(),
593
                $this->course->getCode(),
594
                $sessionId
595
            ),
596
        ];
597
    }
598
599
    /**
600
     * @throws Exception
601
     *
602
     * @return array
603
     */
604
    public function getCourseAgenda()
605
    {
606
        Event::event_access_tool(TOOL_CALENDAR_EVENT);
607
608
        $sessionId = $this->session ? $this->session->getId() : 0;
609
610
        $agenda = new Agenda(
611
            'course',
612
            $this->user->getId(),
613
            $this->course->getId(),
614
            $sessionId
615
        );
616
        $result = $agenda->parseAgendaFilter(null);
617
618
        $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
619
        $start->modify('first day of this month');
620
        $start->setTime(0, 0, 0);
621
        $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
622
        $end->modify('last day of this month');
623
        $end->setTime(23, 59, 59);
624
625
        $groupId = current($result['groups']);
626
        $userId = current($result['users']);
627
628
        $events = $agenda->getEvents(
629
            $start->getTimestamp(),
630
            $end->getTimestamp(),
631
            $this->course->getId(),
632
            $groupId,
633
            $userId,
634
            'array'
635
        );
636
637
        if (!is_array($events)) {
638
            return [];
639
        }
640
641
        $webPath = api_get_path(WEB_PATH);
642
643
        return array_map(
644
            function ($event) use ($webPath) {
645
                return [
646
                    'id' => (int) $event['unique_id'],
647
                    'title' => $event['title'],
648
                    'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
649
                    'startDate' => $event['start_date_localtime'],
650
                    'endDate' => $event['end_date_localtime'],
651
                    'isAllDay' => $event['allDay'] ? true : false,
652
                ];
653
            },
654
            $events
655
        );
656
    }
657
658
    /**
659
     * @throws Exception
660
     *
661
     * @return array
662
     */
663
    public function getCourseNotebooks()
664
    {
665
        Event::event_access_tool(TOOL_NOTEBOOK);
666
667
        $em = Database::getManager();
668
        /** @var CNotebookRepository $notebooksRepo */
669
        $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
670
        $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
671
672
        return array_map(
673
            function (CNotebook $notebook) {
674
                return [
675
                    'id' => $notebook->getIid(),
676
                    'title' => $notebook->getTitle(),
677
                    'description' => $notebook->getDescription(),
678
                    'creationDate' => api_format_date(
679
                        $notebook->getCreationDate()->getTimestamp()
680
                    ),
681
                    'updateDate' => api_format_date(
682
                        $notebook->getUpdateDate()->getTimestamp()
683
                    ),
684
                ];
685
            },
686
            $notebooks
687
        );
688
    }
689
690
    /**
691
     * @throws Exception
692
     *
693
     * @return array
694
     */
695
    public function getCourseForumCategories()
696
    {
697
        Event::event_access_tool(TOOL_FORUM);
698
699
        $sessionId = $this->session ? $this->session->getId() : 0;
700
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
701
702
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
703
704
        $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
705
        $categories = [];
706
        $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
707
        $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
708
        $forums = [];
709
710
        foreach ($forumsFullData as $forumId => $forumInfo) {
711
            $forum = [
712
                'id' => (int) $forumInfo['iid'],
713
                'catId' => (int) $forumInfo['forum_category'],
714
                'title' => $forumInfo['forum_title'],
715
                'description' => $forumInfo['forum_comment'],
716
                'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
717
                'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval(
718
                    $forumInfo['number_of_threads']
719
                ) : 0,
720
                'lastPost' => null,
721
            ];
722
723
            $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
724
725
            if ($lastPostInfo) {
726
                $forum['lastPost'] = [
727
                    'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
728
                    'user' => api_get_person_name(
729
                        $lastPostInfo['last_poster_firstname'],
730
                        $lastPostInfo['last_poster_lastname']
731
                    ),
732
                ];
733
            }
734
735
            $forums[] = $forum;
736
        }
737
738
        foreach ($categoriesFullData as $category) {
739
            $categoryForums = array_filter(
740
                $forums,
741
                function (array $forum) use ($category) {
742
                    if ($forum['catId'] != $category['cat_id']) {
743
                        return false;
744
                    }
745
746
                    return true;
747
                }
748
            );
749
750
            $categories[] = [
751
                'id' => (int) $category['iid'],
752
                'title' => $category['cat_title'],
753
                'catId' => (int) $category['cat_id'],
754
                'description' => $category['cat_comment'],
755
                'forums' => $categoryForums,
756
                'courseId' => $this->course->getId(),
757
            ];
758
        }
759
760
        return $categories;
761
    }
762
763
    /**
764
     * @param int $forumId
765
     *
766
     * @throws Exception
767
     *
768
     * @return array
769
     */
770
    public function getCourseForum($forumId)
771
    {
772
        Event::event_access_tool(TOOL_FORUM);
773
774
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
775
776
        $sessionId = $this->session ? $this->session->getId() : 0;
777
        $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
778
779
        if (!isset($forumInfo['iid'])) {
780
            throw new Exception(get_lang('NoForum'));
781
        }
782
783
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
784
        $forum = [
785
            'id' => $forumInfo['iid'],
786
            'title' => $forumInfo['forum_title'],
787
            'description' => $forumInfo['forum_comment'],
788
            'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
789
            'threads' => [],
790
        ];
791
792
        $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
793
794
        foreach ($threads as $thread) {
795
            $forum['threads'][] = [
796
                'id' => $thread['iid'],
797
                'title' => $thread['thread_title'],
798
                'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
799
                'numberOfReplies' => $thread['thread_replies'],
800
                'numberOfViews' => $thread['thread_views'],
801
                'author' => api_get_person_name($thread['firstname'], $thread['lastname']),
802
            ];
803
        }
804
805
        return $forum;
806
    }
807
808
    /**
809
     * @param int $forumId
810
     * @param int $threadId
811
     *
812
     * @return array
813
     */
814
    public function getCourseForumThread($forumId, $threadId)
815
    {
816
        Event::event_access_tool(TOOL_FORUM);
817
818
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
819
820
        $sessionId = $this->session ? $this->session->getId() : 0;
821
        $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
822
823
        $thread = [
824
            'id' => intval($threadInfo['iid']),
825
            'cId' => intval($threadInfo['c_id']),
826
            'title' => $threadInfo['thread_title'],
827
            'forumId' => intval($threadInfo['forum_id']),
828
            'posts' => [],
829
        ];
830
831
        $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
832
        $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
833
834
        foreach ($postsInfo as $postInfo) {
835
            $thread['posts'][] = [
836
                'id' => $postInfo['iid'],
837
                'title' => $postInfo['post_title'],
838
                'text' => $postInfo['post_text'],
839
                'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
840
                'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
841
                'parentId' => $postInfo['post_parent_id'],
842
            ];
843
        }
844
845
        return $thread;
846
    }
847
848
    /**
849
     * @return array
850
     */
851
    public function getUserProfile()
852
    {
853
        $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
854
855
        $result = [
856
            'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
857
            'id' => $this->user->getId(),
858
            'status' => $this->user->getStatus(),
859
            'fullName' => UserManager::formatUserFullName($this->user),
860
            'username' => $this->user->getUsername(),
861
            'officialCode' => $this->user->getOfficialCode(),
862
            'phone' => $this->user->getPhone(),
863
            'extra' => [],
864
        ];
865
866
        $fieldValue = new ExtraFieldValue('user');
867
        $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
868
869
        foreach ($extraInfo as $extra) {
870
            /** @var ExtraFieldValues $extraValue */
871
            $extraValue = $extra['value'];
872
            $result['extra'][] = [
873
                'title' => $extraValue->getField()->getDisplayText(true),
874
                'value' => $extraValue->getValue(),
875
            ];
876
        }
877
878
        return $result;
879
    }
880
881
    public function getCourseLpProgress()
882
    {
883
        $sessionId = $this->session ? $this->session->getId() : 0;
884
        $userId = $this->user->getId();
885
886
        /*$sessionId = $this->session ? $this->session->getId() : 0;
887
        $courseId = $this->course->getId();*/
888
889
        $result = Tracking::getCourseLpProgress($userId, $sessionId);
890
891
        return [$result];
892
    }
893
894
    /**
895
     * @throws Exception
896
     *
897
     * @return array
898
     */
899
    public function getCourseLearnPaths()
900
    {
901
        Event::event_access_tool(TOOL_LEARNPATH);
902
903
        $sessionId = $this->session ? $this->session->getId() : 0;
904
        $categoriesTempList = learnpath::getCategories($this->course->getId());
905
906
        $categoryNone = new CLpCategory();
907
        $categoryNone->setId(0);
908
        $categoryNone->setName(get_lang('WithOutCategory'));
909
        $categoryNone->setPosition(0);
910
911
        $categories = array_merge([$categoryNone], $categoriesTempList);
912
        $categoryData = [];
913
914
        /** @var CLpCategory $category */
915
        foreach ($categories as $category) {
916
            $learnPathList = new LearnpathList(
917
                $this->user->getId(),
918
                api_get_course_info($this->course->getCode()),
919
                $sessionId,
920
                null,
921
                false,
922
                $category->getId()
923
            );
924
925
            $flatLpList = $learnPathList->get_flat_list();
926
927
            if (empty($flatLpList)) {
928
                continue;
929
            }
930
931
            $listData = [];
932
933
            foreach ($flatLpList as $lpId => $lpDetails) {
934
                if ($lpDetails['lp_visibility'] == 0) {
935
                    continue;
936
                }
937
938
                if (!learnpath::is_lp_visible_for_student(
939
                    $lpId,
940
                    $this->user->getId(),
941
                    api_get_course_info($this->course->getCode()),
942
                    $sessionId
943
                )) {
944
                    continue;
945
                }
946
947
                $timeLimits = false;
948
949
                // This is an old LP (from a migration 1.8.7) so we do nothing
950
                if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
951
                    $timeLimits = false;
952
                }
953
954
                // Checking if expired_on is ON
955
                if (!empty($lpDetails['expired_on'])) {
956
                    $timeLimits = true;
957
                }
958
959
                if ($timeLimits) {
960
                    if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
961
                        $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
962
                        $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
963
                        $now = time();
964
                        $isActiveTime = false;
965
966
                        if ($now > $startTime && $endTime > $now) {
967
                            $isActiveTime = true;
968
                        }
969
970
                        if (!$isActiveTime) {
971
                            continue;
972
                        }
973
                    }
974
                }
975
976
                $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
977
978
                $listData[] = [
979
                    'id' => $lpId,
980
                    'title' => Security::remove_XSS($lpDetails['lp_name']),
981
                    'progress' => $progress,
982
                    'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query(
983
                        [
984
                            'hash' => $this->encodeParams(
985
                                [
986
                                    'action' => 'course_learnpath',
987
                                    'lp_id' => $lpId,
988
                                    'course' => $this->course->getId(),
989
                                    'session' => $sessionId,
990
                                ]
991
                            ),
992
                        ]
993
                    ),
994
                ];
995
            }
996
997
            if (empty($listData)) {
998
                continue;
999
            }
1000
1001
            $categoryData[] = [
1002
                'id' => $category->getId(),
1003
                'name' => $category->getName(),
1004
                'learnpaths' => $listData,
1005
            ];
1006
        }
1007
1008
        return $categoryData;
1009
    }
1010
1011
    /**
1012
     * Start login for a user. Then make a redirect to show the learnpath.
1013
     *
1014
     * @param int $lpId
1015
     */
1016
    public function showLearningPath($lpId)
1017
    {
1018
        $loggedUser['user_id'] = $this->user->getId();
1019
        $loggedUser['status'] = $this->user->getStatus();
1020
        $loggedUser['uidReset'] = true;
1021
        $sessionId = $this->session ? $this->session->getId() : 0;
1022
1023
        ChamiloSession::write('_user', $loggedUser);
1024
        Login::init_user($this->user->getId(), true);
1025
1026
        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query(
1027
            [
1028
                'cidReq' => $this->course->getCode(),
1029
                'id_session' => $sessionId,
1030
                'gidReq' => 0,
1031
                'gradebook' => 0,
1032
                'origin' => '',
1033
                'action' => 'view',
1034
                'lp_id' => (int) $lpId,
1035
                'isStudentView' => 'true',
1036
            ]
1037
        );
1038
1039
        header("Location: $url");
1040
        exit;
1041
    }
1042
1043
    /**
1044
     * @param int $forumId
1045
     *
1046
     * @return array
1047
     */
1048
    public function saveForumPost(array $postValues, $forumId)
1049
    {
1050
        Event::event_access_tool(TOOL_FORUM);
1051
1052
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1053
1054
        $forum = get_forums($forumId, $this->course->getCode());
1055
        store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
1056
1057
        return [
1058
            'registered' => true,
1059
        ];
1060
    }
1061
1062
    /**
1063
     * Get the list of sessions for current user.
1064
     *
1065
     * @return array the sessions list
1066
     */
1067
    public function getUserSessions()
1068
    {
1069
        $data = [];
1070
        $sessionsByCategory = UserManager::get_sessions_by_category($this->user->getId(), false);
1071
1072
        foreach ($sessionsByCategory as $category) {
1073
            $categorySessions = [];
1074
1075
            foreach ($category['sessions'] as $sessions) {
1076
                $sessionCourses = [];
1077
1078
                foreach ($sessions['courses'] as $course) {
1079
                    $courseInfo = api_get_course_info_by_id($course['real_id']);
1080
                    $teachers = SessionManager::getCoachesByCourseSessionToString(
1081
                        $sessions['session_id'],
1082
                        $course['real_id']
1083
                    );
1084
1085
                    $sessionCourses[] = [
1086
                        'id' => $courseInfo['real_id'],
1087
                        'title' => $courseInfo['title'],
1088
                        'code' => $courseInfo['code'],
1089
                        'directory' => $courseInfo['directory'],
1090
                        'pictureUrl' => $courseInfo['course_image_large'],
1091
                        'urlPicture' => $courseInfo['course_image_large'],
1092
                        'teachers' => $teachers,
1093
                    ];
1094
                }
1095
1096
                $sessionBox = Display::getSessionTitleBox($sessions['session_id']);
1097
1098
                $categorySessions[] = [
1099
                    'name' => $sessionBox['title'],
1100
                    'id' => $sessions['session_id'],
1101
                    'date' => $sessionBox['dates'],
1102
                    'duration' => isset($sessionBox['duration']) ? $sessionBox['duration'] : null,
1103
                    'courses' => $sessionCourses,
1104
                ];
1105
            }
1106
1107
            $data[] = [
1108
                'id' => $category['session_category']['id'],
1109
                'name' => $category['session_category']['name'],
1110
                'sessions' => $categorySessions,
1111
            ];
1112
        }
1113
1114
        return $data;
1115
    }
1116
1117
    public function getUsersSubscribedToCourse()
1118
    {
1119
        $users = CourseManager::get_user_list_from_course_code($this->course->getCode());
1120
1121
        $userList = [];
1122
        foreach ($users as $user) {
1123
            $userList[] = [
1124
                'user_id' => $user['user_id'],
1125
                'username' => $user['username'],
1126
                'firstname' => $user['firstname'],
1127
                'lastname' => $user['lastname'],
1128
                'status_rel' => $user['status_rel'],
1129
            ];
1130
        }
1131
1132
        return $userList;
1133
    }
1134
1135
    /**
1136
     * @param string $subject
1137
     * @param string $text
1138
     *
1139
     * @return array
1140
     */
1141
    public function saveUserMessage($subject, $text, array $receivers)
1142
    {
1143
        foreach ($receivers as $userId) {
1144
            MessageManager::send_message($userId, $subject, $text);
1145
        }
1146
1147
        return [
1148
            'sent' => true,
1149
        ];
1150
    }
1151
1152
    /**
1153
     * @param string $search
1154
     *
1155
     * @return array
1156
     */
1157
    public function getMessageUsers($search)
1158
    {
1159
        $repo = UserManager::getRepository();
1160
1161
        $users = $repo->findUsersToSendMessage($this->user->getId(), $search);
1162
        $showEmail = api_get_setting('show_email_addresses') === 'true';
1163
        $data = [];
1164
1165
        /** @var User $user */
1166
        foreach ($users as $user) {
1167
            $userName = UserManager::formatUserFullName($user);
1168
1169
            if ($showEmail) {
1170
                $userName .= " ({$user->getEmail()})";
1171
            }
1172
1173
            $data[] = [
1174
                'id' => $user->getId(),
1175
                'name' => $userName,
1176
            ];
1177
        }
1178
1179
        return $data;
1180
    }
1181
1182
    /**
1183
     * @param string $title
1184
     * @param string $text
1185
     *
1186
     * @return array
1187
     */
1188
    public function saveCourseNotebook($title, $text)
1189
    {
1190
        Event::event_access_tool(TOOL_NOTEBOOK);
1191
1192
        $values = ['note_title' => $title, 'note_comment' => $text];
1193
        $sessionId = $this->session ? $this->session->getId() : 0;
1194
1195
        $noteBookId = NotebookManager::save_note(
1196
            $values,
1197
            $this->user->getId(),
1198
            $this->course->getId(),
1199
            $sessionId
1200
        );
1201
1202
        return [
1203
            'registered' => $noteBookId,
1204
        ];
1205
    }
1206
1207
    /**
1208
     * @param int $forumId
1209
     *
1210
     * @return array
1211
     */
1212
    public function saveForumThread(array $values, $forumId)
1213
    {
1214
        Event::event_access_tool(TOOL_FORUM);
1215
1216
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1217
1218
        $sessionId = $this->session ? $this->session->getId() : 0;
1219
        $forum = get_forums($forumId, $this->course->getCode(), true, $sessionId);
1220
        $courseInfo = api_get_course_info($this->course->getCode());
1221
        $thread = store_thread($forum, $values, $courseInfo, false, $this->user->getId(), $sessionId);
1222
1223
        return [
1224
            'registered' => $thread->getIid(),
1225
        ];
1226
    }
1227
1228
    /**
1229
     * @return array
1230
     */
1231
    public function getUsersCampus(array $params)
1232
    {
1233
        $conditions = [
1234
            'status' => $params['status'],
1235
        ];
1236
        $idCampus = $params['id_campus'];
1237
        $users = UserManager::get_user_list($conditions, ['firstname'], false, false, $idCampus);
1238
        $list = [];
1239
        foreach ($users as $item) {
1240
            $listTemp = [
1241
                'id' => $item['user_id'],
1242
                'firstname' => $item['firstname'],
1243
                'lastname' => $item['lastname'],
1244
                'email' => $item['email'],
1245
            ];
1246
            $list[] = $listTemp;
1247
        }
1248
1249
        return $list;
1250
    }
1251
1252
    /**
1253
     * @return array
1254
     */
1255
    public function getCoursesCampus(array $params)
1256
    {
1257
        $idCampus = $params['id_campus'];
1258
1259
        return CourseManager::get_courses_list(
1260
            0, //offset
1261
            0, //howMany
1262
            1, //$orderby = 1
1263
            'ASC',
1264
            -1, //visibility
1265
            null,
1266
            $idCampus, //$urlId
1267
            true //AlsoSearchCode
1268
        );
1269
    }
1270
1271
    /**
1272
     * @return array
1273
     */
1274
    public function addSession(array $params)
1275
    {
1276
        $name = $params['name'];
1277
        $coach_username = (int) $params['coach_username'];
1278
        $startDate = $params['access_start_date'];
1279
        $endDate = $params['access_end_date'];
1280
        $displayStartDate = $startDate;
1281
        $displayEndDate = $endDate;
1282
        $description = $params['description'];
1283
        $idUrlCampus = $params['id_campus'];
1284
        $extraFields = isset($params['extra']) ? $params['extra'] : [];
1285
1286
        $return = SessionManager::create_session(
1287
            $name,
1288
            $startDate,
1289
            $endDate,
1290
            $displayStartDate,
1291
            $displayEndDate,
1292
            null,
1293
            null,
1294
            $coach_username,
1295
            null,
1296
            1,
1297
            false,
1298
            null,
1299
            $description,
1300
            1,
1301
            $extraFields,
1302
            null,
1303
            false,
1304
            $idUrlCampus
1305
        );
1306
1307
        if ($return) {
1308
            $out = [
1309
                'status' => true,
1310
                'message' => get_lang('ANewSessionWasCreated'),
1311
                'id_session' => $return,
1312
            ];
1313
        } else {
1314
            $out = [
1315
                'status' => false,
1316
                'message' => get_lang('ErrorOccurred'),
1317
            ];
1318
        }
1319
1320
        return $out;
1321
    }
1322
1323
    public function addCourse(array $courseParam): array
1324
    {
1325
        $idCampus = isset($courseParam['id_campus']) ? $courseParam['id_campus'] : 1;
1326
        $title = isset($courseParam['title']) ? $courseParam['title'] : '';
1327
        $wantedCode = isset($courseParam['wanted_code']) ? $courseParam['wanted_code'] : null;
1328
        $diskQuota = isset($courseParam['disk_quota']) ? $courseParam['disk_quota'] : '100';
1329
        $visibility = isset($courseParam['visibility']) ? (int) $courseParam['visibility'] : null;
1330
        $removeCampusId = $courseParam['remove_campus_id_from_wanted_code'] ?? 0;
1331
        $language = $courseParam['language'] ?? '';
1332
1333
        if (isset($courseParam['visibility'])) {
1334
            if ($courseParam['visibility'] &&
1335
                $courseParam['visibility'] >= 0 &&
1336
                $courseParam['visibility'] <= 3
1337
            ) {
1338
                $visibility = (int) $courseParam['visibility'];
1339
            }
1340
        }
1341
1342
        $params = [];
1343
        $params['title'] = $title;
1344
        $params['wanted_code'] = 'CAMPUS_'.$idCampus.'_'.$wantedCode;
1345
        if (1 === (int) $removeCampusId) {
1346
            $params['wanted_code'] = $wantedCode;
1347
        }
1348
        $params['user_id'] = $this->user->getId();
1349
        $params['visibility'] = $visibility;
1350
        $params['disk_quota'] = $diskQuota;
1351
        $params['course_language'] = $language;
1352
1353
        foreach ($courseParam as $key => $value) {
1354
            if (substr($key, 0, 6) === 'extra_') { //an extra field
1355
                $params[$key] = $value;
1356
            }
1357
        }
1358
1359
        $courseInfo = CourseManager::create_course($params, $params['user_id'], $idCampus);
1360
        $results = [];
1361
        if (!empty($courseInfo)) {
1362
            $results['status'] = true;
1363
            $results['code_course'] = $courseInfo['code'];
1364
            $results['title_course'] = $courseInfo['title'];
1365
            $extraFieldValues = new ExtraFieldValue('course');
1366
            $extraFields = $extraFieldValues->getAllValuesByItem($courseInfo['real_id']);
1367
            $results['extra_fields'] = $extraFields;
1368
            $results['message'] = sprintf(get_lang('CourseXAdded'), $courseInfo['code']);
1369
        } else {
1370
            $results['status'] = false;
1371
            $results['message'] = get_lang('CourseCreationFailed');
1372
        }
1373
1374
        return $results;
1375
    }
1376
1377
    /**
1378
     * @param $userParam
1379
     *
1380
     * @throws Exception
1381
     *
1382
     * @return array
1383
     */
1384
    public function addUser($userParam)
1385
    {
1386
        $firstName = $userParam['firstname'];
1387
        $lastName = $userParam['lastname'];
1388
        $status = $userParam['status'];
1389
        $email = $userParam['email'];
1390
        $loginName = $userParam['loginname'];
1391
        $password = $userParam['password'];
1392
1393
        $official_code = '';
1394
        $language = '';
1395
        $phone = '';
1396
        $picture_uri = '';
1397
        $auth_source = $userParam['auth_source'] ?? PLATFORM_AUTH_SOURCE;
1398
        $expiration_date = '';
1399
        $active = 1;
1400
        $hr_dept_id = 0;
1401
        $original_user_id_name = $userParam['original_user_id_name'];
1402
        $original_user_id_value = $userParam['original_user_id_value'];
1403
1404
        $extra_list = isset($userParam['extra']) ? $userParam['extra'] : [];
1405
        if (isset($userParam['language'])) {
1406
            $language = $userParam['language'];
1407
        }
1408
        if (isset($userParam['phone'])) {
1409
            $phone = $userParam['phone'];
1410
        }
1411
        if (isset($userParam['expiration_date'])) {
1412
            $expiration_date = $userParam['expiration_date'];
1413
        }
1414
1415
        // Default language.
1416
        if (empty($language)) {
1417
            $language = api_get_setting('platformLanguage');
1418
        }
1419
1420
        // First check wether the login already exists.
1421
        if (!UserManager::is_username_available($loginName)) {
1422
            throw new Exception(get_lang('UserNameNotAvailable'));
1423
        }
1424
1425
        $userId = UserManager::create_user(
1426
            $firstName,
1427
            $lastName,
1428
            $status,
1429
            $email,
1430
            $loginName,
1431
            $password,
1432
            $official_code,
1433
            $language,
1434
            $phone,
1435
            $picture_uri,
1436
            $auth_source,
1437
            $expiration_date,
1438
            $active,
1439
            $hr_dept_id
1440
        );
1441
1442
        if (empty($userId)) {
1443
            throw new Exception(get_lang('UserNotRegistered'));
1444
        }
1445
1446
        if (api_is_multiple_url_enabled()) {
1447
            if (api_get_current_access_url_id() != -1) {
1448
                UrlManager::add_user_to_url(
1449
                    $userId,
1450
                    api_get_current_access_url_id()
1451
                );
1452
            } else {
1453
                UrlManager::add_user_to_url($userId, 1);
1454
            }
1455
        } else {
1456
            // We add by default the access_url_user table with access_url_id = 1
1457
            UrlManager::add_user_to_url($userId, 1);
1458
        }
1459
1460
        // Save new field label into user_field table.
1461
        UserManager::create_extra_field(
1462
            $original_user_id_name,
1463
            1,
1464
            $original_user_id_name,
1465
            ''
1466
        );
1467
        // Save the external system's id into user_field_value table.
1468
        UserManager::update_extra_field_value(
1469
            $userId,
1470
            $original_user_id_name,
1471
            $original_user_id_value
1472
        );
1473
1474
        if (is_array($extra_list) && count($extra_list) > 0) {
1475
            foreach ($extra_list as $extra) {
1476
                $extra_field_name = $extra['field_name'];
1477
                $extra_field_value = $extra['field_value'];
1478
                // Save new field label into user_field table.
1479
                UserManager::create_extra_field(
1480
                    $extra_field_name,
1481
                    1,
1482
                    $extra_field_name,
1483
                    ''
1484
                );
1485
                // Save the external system's id into user_field_value table.
1486
                UserManager::update_extra_field_value(
1487
                    $userId,
1488
                    $extra_field_name,
1489
                    $extra_field_value
1490
                );
1491
            }
1492
        }
1493
1494
        return [$userId];
1495
    }
1496
1497
    /**
1498
     * Subscribe User to Course.
1499
     *
1500
     * @param array $params
1501
     *
1502
     * @return array
1503
     */
1504
    public function subscribeUserToCourse($params)
1505
    {
1506
        $course_id = $params['course_id'];
1507
        $course_code = $params['course_code'];
1508
        $user_id = $params['user_id'];
1509
        $status = $params['status'] ?? STUDENT;
1510
1511
        if (!$course_id && !$course_code) {
1512
            return [false];
1513
        }
1514
        if (!$course_code) {
1515
            $course_code = CourseManager::get_course_code_from_course_id($course_id);
1516
        }
1517
1518
        if (CourseManager::subscribeUser($user_id, $course_code, $status, 0, 0, false)) {
1519
            return [true];
1520
        }
1521
1522
        return [false];
1523
    }
1524
1525
    public function unSubscribeUserToCourse(array $params): array
1526
    {
1527
        $courseId = $params['course_id'];
1528
        $courseCode = $params['course_code'];
1529
        $userId = $params['user_id'];
1530
1531
        if (!$courseId && !$courseCode) {
1532
            return [false];
1533
        }
1534
1535
        if (!$courseCode) {
1536
            $courseCode = CourseManager::get_course_code_from_course_id($courseId);
1537
        }
1538
1539
        if (CourseManager::unsubscribe_user($userId, $courseCode)) {
1540
            return [true];
1541
        }
1542
1543
        return [false];
1544
    }
1545
1546
    public function deleteUserMessage($messageId, $messageType)
1547
    {
1548
        if ($messageType === 'sent') {
1549
            return MessageManager::delete_message_by_user_sender($this->user->getId(), $messageId);
1550
        } else {
1551
            return MessageManager::delete_message_by_user_receiver($this->user->getId(), $messageId);
1552
        }
1553
    }
1554
1555
    public function setMessageRead($messageId)
1556
    {
1557
        MessageManager::update_message($this->user->getId(), $messageId);
1558
    }
1559
1560
    /**
1561
     * Add Campus Virtual.
1562
     *
1563
     * @param array Params Campus
1564
     *
1565
     * @return array
1566
     */
1567
    public function createCampusURL($params)
1568
    {
1569
        $urlCampus = Security::remove_XSS($params['url']);
1570
        $description = Security::remove_XSS($params['description']);
1571
1572
        $active = isset($params['active']) ? intval($params['active']) : 0;
1573
        $num = UrlManager::url_exist($urlCampus);
1574
        if ($num == 0) {
1575
            // checking url
1576
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1577
                $idCampus = UrlManager::add($urlCampus, $description, $active, true);
1578
            } else {
1579
                //create
1580
                $idCampus = UrlManager::add($urlCampus.'/', $description, $active, true);
1581
            }
1582
1583
            return [
1584
                'status' => true,
1585
                'id_campus' => $idCampus,
1586
            ];
1587
        }
1588
1589
        return [
1590
            'status' => false,
1591
            'id_campus' => 0,
1592
        ];
1593
    }
1594
1595
    /**
1596
     * Edit Campus Virtual.
1597
     *
1598
     * @param array Params Campus
1599
     *
1600
     * @return array
1601
     */
1602
    public function editCampusURL($params)
1603
    {
1604
        $urlCampus = Security::remove_XSS($params['url']);
1605
        $description = Security::remove_XSS($params['description']);
1606
1607
        $active = isset($params['active']) ? intval($params['active']) : 0;
1608
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1609
1610
        if (!empty($url_id)) {
1611
            //we can't change the status of the url with id=1
1612
            if ($url_id == 1) {
1613
                $active = 1;
1614
            }
1615
            //checking url
1616
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1617
                UrlManager::update($url_id, $urlCampus, $description, $active);
1618
            } else {
1619
                UrlManager::update($url_id, $urlCampus.'/', $description, $active);
1620
            }
1621
1622
            return [true];
1623
        }
1624
1625
        return [false];
1626
    }
1627
1628
    /**
1629
     * Delete Campus Virtual.
1630
     *
1631
     * @param array Params Campus
1632
     *
1633
     * @return array
1634
     */
1635
    public function deleteCampusURL($params)
1636
    {
1637
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1638
1639
        $result = UrlManager::delete($url_id);
1640
        if ($result) {
1641
            return [
1642
                'status' => true,
1643
                'message' => get_lang('URLDeleted'),
1644
            ];
1645
        } else {
1646
            return [
1647
                'status' => false,
1648
                'message' => get_lang('Error'),
1649
            ];
1650
        }
1651
    }
1652
1653
    /**
1654
     * @throws Exception
1655
     *
1656
     * @return array
1657
     */
1658
    public function addCoursesSession(array $params)
1659
    {
1660
        $sessionId = $params['id_session'];
1661
        $courseList = $params['list_courses'];
1662
        $importAssignments = isset($params['import_assignments']) ? 1 === (int) $params['import_assignments'] : false;
1663
1664
        $result = SessionManager::add_courses_to_session(
1665
            $sessionId,
1666
            $courseList,
1667
            true,
1668
            false,
1669
            false,
1670
            $importAssignments
1671
        );
1672
1673
        if ($result) {
1674
            return [
1675
                'status' => $result,
1676
                'message' => get_lang('Updated'),
1677
            ];
1678
        }
1679
1680
        return [
1681
            'status' => $result,
1682
            'message' => get_lang('ErrorOccurred'),
1683
        ];
1684
    }
1685
1686
    /**
1687
     * @return array
1688
     */
1689
    public function addUsersSession(array $params)
1690
    {
1691
        $sessionId = $params['id_session'];
1692
        $userList = $params['list_users'];
1693
1694
        if (!is_array($userList)) {
1695
            $userList = [];
1696
        }
1697
1698
        SessionManager::subscribeUsersToSession(
1699
            $sessionId,
1700
            $userList,
1701
            null,
1702
            false
1703
        );
1704
1705
        return [
1706
            'status' => true,
1707
            'message' => get_lang('UsersAdded'),
1708
        ];
1709
    }
1710
1711
    /**
1712
     * Creates a session from a model session.
1713
     *
1714
     * @param $modelSessionId
1715
     * @param $sessionName
1716
     * @param $startDate
1717
     * @param $endDate
1718
     *
1719
     * @throws Exception
1720
     *
1721
     * @return int, the id of the new session
1722
     */
1723
    public function createSessionFromModel($modelSessionId, $sessionName, $startDate, $endDate, array $extraFields = [])
1724
    {
1725
        if (empty($modelSessionId) || empty($sessionName) || empty($startDate) || empty($endDate)) {
1726
            throw new Exception(get_lang('NoData'));
1727
        }
1728
1729
        if (!SessionManager::isValidId($modelSessionId)) {
1730
            throw new Exception(get_lang('ModelSessionDoesNotExist'));
1731
        }
1732
1733
        $modelSession = SessionManager::fetch($modelSessionId);
1734
1735
        $modelSession['accessUrlId'] = 1;
1736
        if (api_is_multiple_url_enabled()) {
1737
            if (api_get_current_access_url_id() != -1) {
1738
                $modelSession['accessUrlId'] = api_get_current_access_url_id();
1739
            }
1740
        }
1741
1742
        $newSessionId = SessionManager::create_session(
1743
            $sessionName,
1744
            $startDate,
1745
            $endDate,
1746
            $startDate,
1747
            $endDate,
1748
            $startDate,
1749
            $endDate,
1750
            $modelSession['id_coach'],
1751
            $modelSession['session_category_id'],
1752
            $modelSession['visibility'],
1753
            false,
1754
            $modelSession['duration'],
1755
            $modelSession['description'],
1756
            $modelSession['show_description'],
1757
            $extraFields,
1758
            $modelSession['session_admin_id'],
1759
            $modelSession['send_subscription_notification'],
1760
            $modelSession['accessUrlId']
1761
        );
1762
1763
        if (empty($newSessionId)) {
1764
            throw new Exception(get_lang('SessionNotRegistered'));
1765
        }
1766
1767
        if (is_string($newSessionId)) {
1768
            throw new Exception($newSessionId);
1769
        }
1770
1771
        $promotionId = $modelSession['promotion_id'];
1772
        if ($promotionId) {
1773
            $sessionList = array_keys(SessionManager::get_all_sessions_by_promotion($promotionId));
1774
            $sessionList[] = $newSessionId;
1775
            SessionManager::subscribe_sessions_to_promotion($modelSession['promotion_id'], $sessionList);
1776
        }
1777
1778
        $modelExtraFields = [];
1779
        $fields = SessionManager::getFilteredExtraFields($modelSessionId);
1780
        if (is_array($fields) and !empty($fields)) {
1781
            foreach ($fields as $field) {
1782
                $modelExtraFields[$field['variable']] = $field['value'];
1783
            }
1784
        }
1785
        $allExtraFields = array_merge($modelExtraFields, $extraFields);
1786
        foreach ($allExtraFields as $name => $value) {
1787
            // SessionManager::update_session_extra_field_value returns false when no row is changed,
1788
            // which can happen since extra field values are initialized by SessionManager::create_session
1789
            // therefore we do not throw an exception when false is returned
1790
            SessionManager::update_session_extra_field_value($newSessionId, $name, $value);
1791
        }
1792
1793
        $courseList = array_keys(SessionManager::get_course_list_by_session_id($modelSessionId));
1794
        if (is_array($courseList)
1795
            && !empty($courseList)
1796
            && !SessionManager::add_courses_to_session($newSessionId, $courseList)) {
1797
            throw new Exception(get_lang('CoursesNotAddedToSession'));
1798
        }
1799
1800
        if (api_is_multiple_url_enabled()) {
1801
            if (api_get_current_access_url_id() != -1) {
1802
                UrlManager::add_session_to_url(
1803
                    $newSessionId,
1804
                    api_get_current_access_url_id()
1805
                );
1806
            } else {
1807
                UrlManager::add_session_to_url($newSessionId, 1);
1808
            }
1809
        } else {
1810
            UrlManager::add_session_to_url($newSessionId, 1);
1811
        }
1812
1813
        return $newSessionId;
1814
    }
1815
1816
    /**
1817
     * subscribes a user to a session.
1818
     *
1819
     * @param int    $sessionId the session id
1820
     * @param string $loginName the user's login name
1821
     *
1822
     * @throws Exception
1823
     *
1824
     * @return boolean, whether it worked
1825
     */
1826
    public function subscribeUserToSessionFromUsername($sessionId, $loginName)
1827
    {
1828
        if (!SessionManager::isValidId($sessionId)) {
1829
            throw new Exception(get_lang('SessionNotFound'));
1830
        }
1831
1832
        $userId = UserManager::get_user_id_from_username($loginName);
1833
        if (false === $userId) {
1834
            throw new Exception(get_lang('UserNotFound'));
1835
        }
1836
1837
        $subscribed = SessionManager::subscribeUsersToSession(
1838
            $sessionId,
1839
            [$userId],
1840
            SESSION_VISIBLE_READ_ONLY,
1841
            false
1842
        );
1843
        if (!$subscribed) {
1844
            throw new Exception(get_lang('UserNotSubscribed'));
1845
        }
1846
1847
        return true;
1848
    }
1849
1850
    /**
1851
     * finds the session which has a specific value in a specific extra field.
1852
     *
1853
     * @param $fieldName
1854
     * @param $fieldValue
1855
     *
1856
     * @throws Exception when no session matched or more than one session matched
1857
     *
1858
     * @return int, the matching session id
1859
     */
1860
    public function getSessionFromExtraField($fieldName, $fieldValue)
1861
    {
1862
        // find sessions that that have value in field
1863
        $valueModel = new ExtraFieldValue('session');
1864
        $sessionIdList = $valueModel->get_item_id_from_field_variable_and_field_value(
1865
            $fieldName,
1866
            $fieldValue,
1867
            false,
1868
            false,
1869
            true
1870
        );
1871
1872
        // throw if none found
1873
        if (empty($sessionIdList)) {
1874
            throw new Exception(get_lang('NoSessionMatched'));
1875
        }
1876
1877
        // throw if more than one found
1878
        if (count($sessionIdList) > 1) {
1879
            throw new Exception(get_lang('MoreThanOneSessionMatched'));
1880
        }
1881
1882
        // return sessionId
1883
        return intval($sessionIdList[0]['item_id']);
1884
    }
1885
1886
    /**
1887
     * updates a user identified by its login name.
1888
     *
1889
     * @param array $parameters
1890
     *
1891
     * @throws Exception on failure
1892
     *
1893
     * @return boolean, true on success
1894
     */
1895
    public function updateUserFromUserName($parameters)
1896
    {
1897
        // find user
1898
        $userId = null;
1899
        if (!is_array($parameters) || empty($parameters)) {
1900
            throw new Exception('NoData');
1901
        }
1902
        foreach ($parameters as $name => $value) {
1903
            if (strtolower($name) === 'loginname') {
1904
                $userId = UserManager::get_user_id_from_username($value);
1905
                if (false === $userId) {
1906
                    throw new Exception(get_lang('UserNotFound'));
1907
                }
1908
                break;
1909
            }
1910
        }
1911
        if (is_null($userId)) {
1912
            throw new Exception(get_lang('NoData'));
1913
        }
1914
        /** @var User $user */
1915
        $user = UserManager::getRepository()->find($userId);
1916
        if (empty($user)) {
1917
            throw new Exception(get_lang('CouldNotLoadUser'));
1918
        }
1919
1920
        // tell the world we are about to update a user
1921
        $hook = HookUpdateUser::create();
1922
        if (!empty($hook)) {
1923
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_PRE);
1924
        }
1925
1926
        // apply submitted modifications
1927
        foreach ($parameters as $name => $value) {
1928
            switch (strtolower($name)) {
1929
                case 'email':
1930
                    $user->setEmail($value);
1931
                    break;
1932
                case 'enabled':
1933
                    $user->setEnabled($value);
1934
                    break;
1935
                case 'lastname':
1936
                    $user->setLastname($value);
1937
                    break;
1938
                case 'firstname':
1939
                    $user->setFirstname($value);
1940
                    break;
1941
                case 'phone':
1942
                    $user->setPhone($value);
1943
                    break;
1944
                case 'address':
1945
                    $user->setAddress($value);
1946
                    break;
1947
                case 'roles':
1948
                    $user->setRoles($value);
1949
                    break;
1950
                case 'profile_completed':
1951
                    $user->setProfileCompleted($value);
1952
                    break;
1953
                case 'auth_source':
1954
                    $user->setAuthSource($value);
1955
                    break;
1956
                case 'status':
1957
                    $user->setStatus($value);
1958
                    break;
1959
                case 'official_code':
1960
                    $user->setOfficialCode($value);
1961
                    break;
1962
                case 'picture_uri':
1963
                    $user->setPictureUri($value);
1964
                    break;
1965
                case 'creator_id':
1966
                    $user->setCreatorId($value);
1967
                    break;
1968
                case 'competences':
1969
                    $user->setCompetences($value);
1970
                    break;
1971
                case 'diplomas':
1972
                    $user->setDiplomas($value);
1973
                    break;
1974
                case 'openarea':
1975
                    $user->setOpenArea($value);
1976
                    break;
1977
                case 'teach':
1978
                    $user->setTeach($value);
1979
                    break;
1980
                case 'productions':
1981
                    $user->setProductions($value);
1982
                    break;
1983
                case 'language':
1984
                    $languages = api_get_languages();
1985
                    if (!in_array($value, $languages['folder'])) {
1986
                        throw new Exception(get_lang('LanguageUnavailable'));
1987
                    }
1988
                    $user->setLanguage($value);
1989
                    break;
1990
                case 'registration_date':
1991
                    $user->setRegistrationDate($value);
1992
                    break;
1993
                case 'expiration_date':
1994
                    $user->setExpirationDate(
1995
                        new DateTime(
1996
                            api_get_utc_datetime($value),
1997
                            new DateTimeZone('UTC')
1998
                        )
1999
                    );
2000
                    break;
2001
                case 'active':
2002
                    // see UserManager::update_user() usermanager.lib.php:1205
2003
                    if ($user->getActive() != $value) {
2004
                        $user->setActive($value);
2005
                        Event::addEvent($value ? LOG_USER_ENABLE : LOG_USER_DISABLE, LOG_USER_ID, $userId);
2006
                    }
2007
                    break;
2008
                case 'openid':
2009
                    $user->setOpenId($value);
2010
                    break;
2011
                case 'theme':
2012
                    $user->setTheme($value);
2013
                    break;
2014
                case 'hr_dept_id':
2015
                    $user->setHrDeptId($value);
2016
                    break;
2017
                case 'extra':
2018
                    if (is_array($value)) {
2019
                        if (count($value) > 0) {
2020
                            if (is_array($value[0])) {
2021
                                foreach ($value as $field) {
2022
                                    $fieldName = $field['field_name'];
2023
                                    $fieldValue = $field['field_value'];
2024
                                    if (!isset($fieldName) || !isset($fieldValue) ||
2025
                                        !UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
2026
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.print_r($field, true));
2027
                                    }
2028
                                }
2029
                            } else {
2030
                                foreach ($value as $fieldName => $fieldValue) {
2031
                                    if (!UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
2032
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.$fieldName);
2033
                                    }
2034
                                }
2035
                            }
2036
                        }
2037
                    }
2038
                    break;
2039
                case 'username':
2040
                case 'api_key':
2041
                case 'action':
2042
                case 'loginname':
2043
                    break;
2044
                case 'email_canonical':
2045
                case 'locked':
2046
                case 'expired':
2047
                case 'credentials_expired':
2048
                case 'credentials_expire_at':
2049
                case 'expires_at':
2050
                case 'salt':
2051
                case 'last_login':
2052
                case 'created_at':
2053
                case 'updated_at':
2054
                case 'confirmation_token':
2055
                case 'password_requested_at':
2056
                case 'password': // see UserManager::update_user usermanager.lib.php:1182
2057
                case 'username_canonical':
2058
                default:
2059
                    throw new Exception(get_lang('UnsupportedUpdate')." '$name'");
2060
            }
2061
        }
2062
2063
        // save modifications
2064
        UserManager::getManager()->updateUser($user, true);
2065
2066
        // tell the world we just updated this user
2067
        if (!empty($hook)) {
2068
            $hook->setEventData(['user' => $user]);
2069
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST);
2070
        }
2071
2072
        // invalidate cache for this user
2073
        $cacheAvailable = api_get_configuration_value('apc');
2074
        if ($cacheAvailable === true) {
2075
            $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$userId;
2076
            if (apcu_exists($apcVar)) {
2077
                apcu_delete($apcVar);
2078
            }
2079
        }
2080
2081
        return true;
2082
    }
2083
2084
    /**
2085
     * Returns whether a user login name exists.
2086
     *
2087
     * @param string $loginname the user login name
2088
     *
2089
     * @return bool whether the user login name exists
2090
     */
2091
    public function usernameExist($loginname)
2092
    {
2093
        return false !== api_get_user_info_from_username($loginname);
2094
    }
2095
2096
    /**
2097
     * This service roughly matches what the call to MDL's API core_course_get_contents function returns.
2098
     *
2099
     * @return array
2100
     */
2101
    public function getCourseQuizMdlCompat()
2102
    {
2103
        $userId = $this->user->getId();
2104
        $courseId = $this->course->getId();
2105
        $sessionId = $this->session ? $this->session->getId() : 0;
2106
2107
        $toolVisibility = CourseHome::getToolVisibility(TOOL_QUIZ, $courseId, $sessionId);
2108
2109
        $json = [
2110
            "id" => $this->course->getId(),
2111
            "name" => get_lang('Exercises'),
2112
            "visible" => (int) $toolVisibility,
2113
            "summary" => '',
2114
            "summaryformat" => 1,
2115
            "section" => 1,
2116
            "hiddenbynumsections" => 0,
2117
            "uservisible" => $toolVisibility,
2118
            "modules" => [],
2119
        ];
2120
2121
        $quizIcon = Display::return_icon('quiz.png', '', [], ICON_SIZE_SMALL, false, true);
2122
2123
        $json['modules'] = array_map(
2124
            function (array $exercise) use ($quizIcon) {
2125
                return [
2126
                    'id' => $exercise['id'],
2127
                    'url' => $exercise['url'],
2128
                    'name' => $exercise['name'],
2129
                    'instance' => 1,
2130
                    'visible' => 1,
2131
                    'uservisible' => true,
2132
                    'visibleoncoursepage' => 0,
2133
                    'modicon' => $quizIcon,
2134
                    'modname' => 'quiz',
2135
                    'modplural' => get_lang('Exercises'),
2136
                    'availability' => null,
2137
                    'indent' => 0,
2138
                    'onclick' => '',
2139
                    'afterlink' => null,
2140
                    'customdata' => "",
2141
                    'noviewlink' => false,
2142
                    'completion' => (int) ($exercise[1] > 0),
2143
                ];
2144
            },
2145
            Exercise::exerciseGrid(0, '', $userId, $courseId, $sessionId, true)
2146
        );
2147
2148
        return [$json];
2149
    }
2150
2151
    /**
2152
     * @throws Exception
2153
     */
2154
    public function updateSession(array $params): array
2155
    {
2156
        $id = $params['session_id'];
2157
        $reset = $params['reset'] ?? null;
2158
        $name = $params['name'] ?? null;
2159
        $coachId = isset($params['id_coach']) ? (int) $params['id_coach'] : null;
2160
        $sessionCategoryId = isset($params['session_category_id']) ? (int) $params['session_category_id'] : null;
2161
        $description = $params['description'] ?? null;
2162
        $showDescription = $params['show_description'] ?? null;
2163
        $duration = $params['duration'] ?? null;
2164
        $visibility = $params['visibility'] ?? null;
2165
        $promotionId = $params['promotion_id'] ?? null;
2166
        $displayStartDate = $params['display_start_date'] ?? null;
2167
        $displayEndDate = $params['display_end_date'] ?? null;
2168
        $accessStartDate = $params['access_start_date'] ?? null;
2169
        $accessEndDate = $params['access_end_date'] ?? null;
2170
        $coachStartDate = $params['coach_access_start_date'] ?? null;
2171
        $coachEndDate = $params['coach_access_end_date'] ?? null;
2172
        $sendSubscriptionNotification = $params['send_subscription_notification'] ?? null;
2173
        $extraFields = $params['extra'] ?? [];
2174
2175
        $reset = (bool) $reset;
2176
        $visibility = (int) $visibility;
2177
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
2178
2179
        if (!SessionManager::isValidId($id)) {
2180
            throw new Exception(get_lang('NoData'));
2181
        }
2182
2183
        if (!empty($accessStartDate) && !api_is_valid_date($accessStartDate, 'Y-m-d H:i') &&
2184
            !api_is_valid_date($accessStartDate, 'Y-m-d H:i:s')
2185
        ) {
2186
            throw new Exception(get_lang('InvalidDate'));
2187
        }
2188
2189
        if (!empty($accessEndDate) && !api_is_valid_date($accessEndDate, 'Y-m-d H:i') &&
2190
            !api_is_valid_date($accessEndDate, 'Y-m-d H:i:s')
2191
        ) {
2192
            throw new Exception(get_lang('InvalidDate'));
2193
        }
2194
2195
        if (!empty($accessStartDate) && !empty($accessEndDate) && $accessStartDate >= $accessEndDate) {
2196
            throw new Exception(get_lang('InvalidDate'));
2197
        }
2198
2199
        $values = [];
2200
2201
        if ($reset) {
2202
            $values['name'] = $name;
2203
            $values['id_coach'] = $coachId;
2204
            $values['session_category_id'] = $sessionCategoryId;
2205
            $values['description'] = $description;
2206
            $values['show_description'] = $showDescription;
2207
            $values['duration'] = $duration;
2208
            $values['visibility'] = $visibility;
2209
            $values['promotion_id'] = $promotionId;
2210
            $values['display_start_date'] = !empty($displayStartDate) ? api_get_utc_datetime($displayStartDate) : null;
2211
            $values['display_end_date'] = !empty($displayEndDate) ? api_get_utc_datetime($displayEndDate) : null;
2212
            $values['access_start_date'] = !empty($accessStartDate) ? api_get_utc_datetime($accessStartDate) : null;
2213
            $values['access_end_date'] = !empty($accessEndDate) ? api_get_utc_datetime($accessEndDate) : null;
2214
            $values['coach_access_start_date'] = !empty($coachStartDate) ? api_get_utc_datetime($coachStartDate) : null;
2215
            $values['coach_access_end_date'] = !empty($coachEndDate) ? api_get_utc_datetime($coachEndDate) : null;
2216
            $values['send_subscription_notification'] = $sendSubscriptionNotification;
2217
        } else {
2218
            if (!empty($name)) {
2219
                $values['name'] = $name;
2220
            }
2221
2222
            if (!empty($coachId)) {
2223
                $values['id_coach'] = $coachId;
2224
            }
2225
2226
            if (!empty($sessionCategoryId)) {
2227
                $values['session_category_id'] = $sessionCategoryId;
2228
            }
2229
2230
            if (!empty($description)) {
2231
                $values['description'] = $description;
2232
            }
2233
2234
            if (!empty($showDescription)) {
2235
                $values['show_description'] = $showDescription;
2236
            }
2237
2238
            if (!empty($duration)) {
2239
                $values['duration'] = $duration;
2240
            }
2241
2242
            if (!empty($visibility)) {
2243
                $values['visibility'] = $visibility;
2244
            }
2245
2246
            if (!empty($promotionId)) {
2247
                $values['promotion_id'] = $promotionId;
2248
            }
2249
2250
            if (!empty($displayStartDate)) {
2251
                $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
2252
            }
2253
2254
            if (!empty($displayEndDate)) {
2255
                $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
2256
            }
2257
2258
            if (!empty($accessStartDate)) {
2259
                $values['access_start_date'] = api_get_utc_datetime($accessStartDate);
2260
            }
2261
2262
            if (!empty($accessEndDate)) {
2263
                $values['access_end_date'] = api_get_utc_datetime($accessEndDate);
2264
            }
2265
2266
            if (!empty($coachStartDate)) {
2267
                $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
2268
            }
2269
2270
            if (!empty($coachEndDate)) {
2271
                $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
2272
            }
2273
2274
            if (!empty($sendSubscriptionNotification)) {
2275
                $values['send_subscription_notification'] = $sendSubscriptionNotification;
2276
            }
2277
        }
2278
2279
        Database::update(
2280
            $tblSession,
2281
            $values,
2282
            ['id = ?' => $id]
2283
        );
2284
2285
        if (!empty($extraFields)) {
2286
            $extraFields['item_id'] = $id;
2287
            $sessionFieldValue = new ExtraFieldValue('session');
2288
            $sessionFieldValue->saveFieldValues($extraFields);
2289
        }
2290
2291
        return [
2292
            'status' => true,
2293
            'message' => get_lang('Updated'),
2294
            'id_session' => $id,
2295
        ];
2296
    }
2297
2298
    public function checkConditionalLogin(): bool
2299
    {
2300
        $file = api_get_path(SYS_CODE_PATH).'auth/conditional_login/conditional_login.php';
2301
2302
        if (!file_exists($file)) {
2303
            return true;
2304
        }
2305
2306
        include_once $file;
2307
2308
        if (!isset($login_conditions)) {
2309
            return true;
2310
        }
2311
2312
        foreach ($login_conditions as $condition) {
2313
            //If condition fails we redirect to the URL defined by the condition
2314
            if (!isset($condition['conditional_function'])) {
2315
                continue;
2316
            }
2317
2318
            $function = $condition['conditional_function'];
2319
            $result = $function(['user_id' => $this->user->getId()]);
2320
2321
            if ($result == false) {
2322
                return false;
2323
            }
2324
        }
2325
2326
        return true;
2327
    }
2328
2329
    public function getLegalConditions(): array
2330
    {
2331
        $language = api_get_language_id(
2332
            api_get_interface_language()
2333
        );
2334
2335
        $termPreview = LegalManager::get_last_condition($language);
2336
2337
        if ($termPreview) {
2338
            return $termPreview;
2339
        }
2340
2341
        $language = api_get_language_id(
2342
            api_get_setting('platformLanguage')
2343
        );
2344
2345
        $termPreview = LegalManager::get_last_condition($language);
2346
2347
        if ($termPreview) {
2348
            return $termPreview;
2349
        }
2350
2351
        $language = api_get_language_id('english');
2352
2353
        return LegalManager::get_last_condition($language);
2354
    }
2355
2356
    public function updateConditionAccepted()
2357
    {
2358
        $legalAcceptType = $_POST['legal_accept_type'] ?? null;
2359
2360
        $condArray = explode(':', $legalAcceptType);
2361
        $condArray = array_map('intval', $condArray);
2362
2363
        if (empty($condArray[0]) || empty($condArray[1])) {
2364
            return;
2365
        }
2366
2367
        $conditionToSave = intval($condArray[0]).':'.intval($condArray[1]).':'.time();
2368
2369
        LegalManager::sendEmailToUserBoss(
2370
            $this->user->getId(),
2371
            $conditionToSave
2372
        );
2373
    }
2374
2375
    public function logout()
2376
    {
2377
        online_logout($this->user->getId());
2378
2379
        Event::courseLogout(
2380
            [
2381
                'uid' => $this->user->getId(),
2382
                'cid' => $this->course ? $this->course->getId() : 0,
2383
                'sid' => $this->session ? $this->session->getId() : 0,
2384
            ]
2385
        );
2386
    }
2387
2388
    /**
2389
     * @param array $additionalParams Optional
2390
     *
2391
     * @return string
2392
     */
2393
    private function encodeParams(array $additionalParams = [])
2394
    {
2395
        $params = array_merge(
2396
            $additionalParams,
2397
            [
2398
                'api_key' => $this->apiKey,
2399
                'username' => $this->user->getUsername(),
2400
            ]
2401
        );
2402
2403
        return json_encode($params);
2404
    }
2405
}
2406