Passed
Push — 1.11.x ( 1657fc...a933b7 )
by Angel Fernando Quiroz
10:12
created

Rest::setThreadNotify()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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