Passed
Push — 1.11.x ( a18d33...1657fc )
by Angel Fernando Quiroz
08:16
created

Rest   F

Complexity

Total Complexity 322

Size/Duplication

Total Lines 2493
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 1346
dl 0
loc 2493
rs 0.8
c 5
b 0
f 0
wmc 322

60 Methods

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