Passed
Push — 1.11.x ( 24974d...655124 )
by Angel Fernando Quiroz
20:31
created

Rest::downloadForumPostAttachment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 0
loc 20
rs 9.8666
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
    const VIEW_MESSAGE = 'view_message';
36
37
    const GET_USER_COURSES = 'user_courses';
38
    const GET_USER_SESSIONS = 'user_sessions';
39
40
    const GET_PROFILE = 'user_profile';
41
42
    const GET_COURSE_INFO = 'course_info';
43
    const GET_COURSE_DESCRIPTIONS = 'course_descriptions';
44
    const GET_COURSE_DOCUMENTS = 'course_documents';
45
    const GET_COURSE_ANNOUNCEMENTS = 'course_announcements';
46
    const GET_COURSE_ANNOUNCEMENT = 'course_announcement';
47
    const GET_COURSE_AGENDA = 'course_agenda';
48
    const GET_COURSE_NOTEBOOKS = 'course_notebooks';
49
    const GET_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
50
    const GET_COURSE_FORUM = 'course_forum';
51
    const GET_COURSE_FORUM_THREAD = 'course_forumthread';
52
    const GET_COURSE_LEARNPATHS = 'course_learnpaths';
53
    const GET_COURSE_LEARNPATH = 'course_learnpath';
54
    const GET_COURSE_LP_PROGRESS = 'course_lp_progress';
55
    const GET_COURSE_LINKS = 'course_links';
56
    const GET_COURSE_WORKS = 'course_works';
57
58
    const SAVE_COURSE_NOTEBOOK = 'save_course_notebook';
59
60
    const SAVE_FORUM_POST = 'save_forum_post';
61
    const SAVE_FORUM_THREAD = 'save_forum_thread';
62
    const SET_THREAD_NOTIFY = 'set_thread_notify';
63
    const DOWNLOAD_FORUM_ATTACHMENT= 'download_forum_attachment';
64
65
    const GET_WORK_LIST = 'get_work_list';
66
    const GET_WORK_STUDENTS_WITHOUT_PUBLICATIONS = 'get_work_students_without_publications';
67
    const GET_WORK_USERS = 'get_work_users';
68
    const GET_WORK_STUDENT_LIST = 'get_work_student_list';
69
    const PUT_WORK_STUDENT_ITEM_VISIBILITY = 'put_course_work_visibility';
70
    const DELETE_WORK_STUDENT_ITEM = 'delete_work_student_item';
71
    const DELETE_WORK_CORRECTIONS = 'delete_work_corrections';
72
73
    const VIEW_DOCUMENT_IN_FRAME = 'view_document_in_frame';
74
75
    const VIEW_QUIZ_TOOL = 'view_quiz_tool';
76
77
    const VIEW_SURVEY_TOOL = 'view_survey_tool';
78
79
    const CREATE_CAMPUS = 'add_campus';
80
    const EDIT_CAMPUS = 'edit_campus';
81
    const DELETE_CAMPUS = 'delete_campus';
82
83
    const GET_USERS = 'get_users';
84
    const USERNAME_EXIST = 'username_exist';
85
    const SAVE_USER = 'save_user';
86
    const SAVE_USER_JSON = 'save_user_json';
87
    const UPDATE_USER_FROM_USERNAME = 'update_user_from_username';
88
    const DELETE_USER = 'delete_user';
89
90
    const GET_COURSES = 'get_courses';
91
    const GET_COURSES_FROM_EXTRA_FIELD = 'get_courses_from_extra_field';
92
    const SAVE_COURSE = 'save_course';
93
    const DELETE_COURSE = 'delete_course';
94
95
    const GET_SESSION_FROM_EXTRA_FIELD = 'get_session_from_extra_field';
96
    const SAVE_SESSION = 'save_session';
97
    const CREATE_SESSION_FROM_MODEL = 'create_session_from_model';
98
    const UPDATE_SESSION = 'update_session';
99
100
    const SUBSCRIBE_USER_TO_COURSE = 'subscribe_user_to_course';
101
    const SUBSCRIBE_USER_TO_COURSE_PASSWORD = 'subscribe_user_to_course_password';
102
    const UNSUBSCRIBE_USER_FROM_COURSE = 'unsubscribe_user_from_course';
103
    const GET_USERS_SUBSCRIBED_TO_COURSE = 'get_users_subscribed_to_course';
104
105
    const ADD_COURSES_SESSION = 'add_courses_session';
106
    const ADD_USERS_SESSION = 'add_users_session';
107
    const SUBSCRIBE_USER_TO_SESSION_FROM_USERNAME = 'subscribe_user_to_session_from_username';
108
109
    const GET_COURSE_QUIZ_MDL_COMPAT = 'get_course_quiz_mdl_compat';
110
111
    const UPDATE_USER_PAUSE_TRAINING = 'update_user_pause_training';
112
113
    const CHECK_CONDITIONAL_LOGIN = 'check_conditional_login';
114
    const GET_LEGAL_CONDITIONS = 'get_legal_conditions';
115
    const UPDATE_CONDITION_ACCEPTED = 'update_condition_accepted';
116
117
    /**
118
     * @var Session
119
     */
120
    private $session;
121
122
    /**
123
     * @var Course
124
     */
125
    private $course;
126
127
    /**
128
     * Rest constructor.
129
     *
130
     * @param string $username
131
     * @param string $apiKey
132
     */
133
    public function __construct($username, $apiKey)
134
    {
135
        parent::__construct($username, $apiKey);
136
    }
137
138
    /**
139
     * @param string $username
140
     * @param string $apiKeyToValidate
141
     *
142
     * @throws Exception
143
     *
144
     * @return Rest
145
     */
146
    public static function validate($username, $apiKeyToValidate)
147
    {
148
        $apiKey = self::findUserApiKey($username, self::SERVICE_NAME);
149
150
        if ($apiKey != $apiKeyToValidate) {
151
            throw new Exception(get_lang('InvalidApiKey'));
152
        }
153
154
        return new self($username, $apiKey);
155
    }
156
157
    /**
158
     * Create the gcm_registration_id extra field for users.
159
     */
160
    public static function init()
161
    {
162
        $extraField = new ExtraField('user');
163
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
164
165
        if (empty($fieldInfo)) {
166
            $extraField->save(
167
                [
168
                    'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
169
                    'field_type' => ExtraField::FIELD_TYPE_TEXT,
170
                    'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION,
171
                ]
172
            );
173
        }
174
    }
175
176
    /**
177
     * @param string $encoded
178
     *
179
     * @return array
180
     */
181
    public static function decodeParams($encoded)
182
    {
183
        return json_decode($encoded);
184
    }
185
186
    /**
187
     * Set the current course.
188
     *
189
     * @param int $id
190
     *
191
     * @throws Exception
192
     */
193
    public function setCourse($id)
194
    {
195
        global $_course;
196
197
        if (!$id) {
198
            $this->course = null;
199
200
            ChamiloSession::erase('_real_cid');
201
            ChamiloSession::erase('_cid');
202
            ChamiloSession::erase('_course');
203
204
            return;
205
        }
206
207
        $em = Database::getManager();
208
        /** @var Course $course */
209
        $course = $em->find('ChamiloCoreBundle:Course', $id);
210
211
        if (!$course) {
0 ignored issues
show
introduced by jmontoyaa
$course is of type Chamilo\CoreBundle\Entity\Course, thus it always evaluated to true.
Loading history...
212
            throw new Exception(get_lang('NoCourse'));
213
        }
214
215
        $this->course = $course;
216
217
        $courseInfo = api_get_course_info($course->getCode());
218
        $_course = $courseInfo;
219
220
        ChamiloSession::write('_real_cid', $course->getId());
221
        ChamiloSession::write('_cid', $course->getCode());
222
        ChamiloSession::write('_course', $courseInfo);
223
    }
224
225
    /**
226
     * Set the current session.
227
     *
228
     * @param int $id
229
     *
230
     * @throws Exception
231
     */
232
    public function setSession($id)
233
    {
234
        if (!$id) {
235
            $this->session = null;
236
237
            ChamiloSession::erase('session_name');
238
            ChamiloSession::erase('id_session');
239
240
            return;
241
        }
242
243
        $em = Database::getManager();
244
        /** @var Session $session */
245
        $session = $em->find('ChamiloCoreBundle:Session', $id);
246
247
        if (!$session) {
0 ignored issues
show
introduced by Angel Fernando Quiroz Campos
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
248
            throw new Exception(get_lang('NoSession'));
249
        }
250
251
        $this->session = $session;
252
253
        ChamiloSession::write('session_name', $session->getName());
254
        ChamiloSession::write('id_session', $session->getId());
255
    }
256
257
    /**
258
     * @param string $registrationId
259
     *
260
     * @return bool
261
     */
262
    public function setGcmId($registrationId)
263
    {
264
        $registrationId = Security::remove_XSS($registrationId);
265
        $extraFieldValue = new ExtraFieldValue('user');
266
267
        return $extraFieldValue->save(
268
            [
269
                'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
270
                'value' => $registrationId,
271
                'item_id' => $this->user->getId(),
272
            ]
273
        );
274
    }
275
276
    /**
277
     * @param int $lastMessageId
278
     *
279
     * @return array
280
     */
281
    public function getUserMessages($lastMessageId = 0)
282
    {
283
        $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
284
        $messages = [];
285
286
        foreach ($lastMessages as $message) {
287
            $hasAttachments = MessageManager::hasAttachments($message['id']);
288
289
            $messages[] = [
290
                'id' => $message['id'],
291
                'title' => $message['title'],
292
                'sender' => [
293
                    'id' => $message['user_id'],
294
                    'lastname' => $message['lastname'],
295
                    'firstname' => $message['firstname'],
296
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
297
                ],
298
                'sendDate' => $message['send_date'],
299
                'content' => $message['content'],
300
                'hasAttachments' => $hasAttachments,
301
                'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?'
302
                    .http_build_query(['type' => 1, 'id' => $message['id']]),
303
            ];
304
        }
305
306
        return $messages;
307
    }
308
309
    /**
310
     * @return array
311
     */
312
    public function getUserReceivedMessages()
313
    {
314
        $lastMessages = MessageManager::getReceivedMessages($this->user->getId(), 0);
315
        $messages = [];
316
317
        $webPath = api_get_path(WEB_PATH);
318
319
        foreach ($lastMessages as $message) {
320
            $hasAttachments = MessageManager::hasAttachments($message['id']);
321
            $attachmentList = [];
322
            if ($hasAttachments) {
323
                $attachmentList = MessageManager::getAttachmentList($message['id']);
324
            }
325
            $messages[] = [
326
                'id' => $message['id'],
327
                'title' => $message['title'],
328
                'msgStatus' => $message['msg_status'],
329
                'sender' => [
330
                    'id' => $message['user_id'],
331
                    'lastname' => $message['lastname'],
332
                    'firstname' => $message['firstname'],
333
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
334
                    'pictureUri' => $message['pictureUri'],
335
                ],
336
                'sendDate' => $message['send_date'],
337
                'content' => str_replace('src="/"', $webPath, $message['content']),
338
                'hasAttachments' => $hasAttachments,
339
                'attachmentList' => $attachmentList,
340
                'url' => '',
341
            ];
342
        }
343
344
        return $messages;
345
    }
346
347
    /**
348
     * @return array
349
     */
350
    public function getUserSentMessages()
351
    {
352
        $lastMessages = MessageManager::getSentMessages($this->user->getId(), 0);
353
        $messages = [];
354
355
        foreach ($lastMessages as $message) {
356
            $hasAttachments = MessageManager::hasAttachments($message['id']);
357
358
            $messages[] = [
359
                'id' => $message['id'],
360
                'title' => $message['title'],
361
                'msgStatus' => $message['msg_status'],
362
                'receiver' => [
363
                    'id' => $message['user_id'],
364
                    'lastname' => $message['lastname'],
365
                    'firstname' => $message['firstname'],
366
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
367
                    'pictureUri' => $message['pictureUri'],
368
                ],
369
                'sendDate' => $message['send_date'],
370
                'content' => $message['content'],
371
                'hasAttachments' => $hasAttachments,
372
                'url' => '',
373
            ];
374
        }
375
376
        return $messages;
377
    }
378
379
    /**
380
     * Get the user courses.
381
     */
382
    public function getUserCourses($userId = 0): array
383
    {
384
        if (empty($userId)) {
385
            $userId = $this->user->getId();
386
        }
387
388
        Event::courseLogout(
389
            [
390
                'uid' => $userId,
391
                'cid' => api_get_course_id(),
392
                'sid' => api_get_session_id(),
393
            ]
394
        );
395
396
        $courses = CourseManager::get_courses_list_by_user_id($userId);
397
        $data = [];
398
399
        foreach ($courses as $courseInfo) {
400
            /** @var Course $course */
401
            $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseInfo['real_id']);
402
            $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode());
403
            $picturePath = CourseManager::getPicturePath($course, true)
404
                ?: Display::return_icon('session_default.png', null, null, null, null, true);
405
406
            $data[] = [
407
                'id' => $course->getId(),
408
                'title' => $course->getTitle(),
409
                'code' => $course->getCode(),
410
                'directory' => $course->getDirectory(),
411
                'urlPicture' => $picturePath,
412
                'teachers' => $teachers,
413
                'isSpecial' => !empty($courseInfo['special_course']),
414
            ];
415
        }
416
417
        return $data;
418
    }
419
420
    /**
421
     * @throws Exception
422
     *
423
     * @return array
424
     */
425
    public function getCourseInfo()
426
    {
427
        $teachers = CourseManager::getTeacherListFromCourseCodeToString($this->course->getCode());
428
        $tools = CourseHome::get_tools_category(
429
            TOOL_STUDENT_VIEW,
430
            $this->course->getId(),
431
            $this->session ? $this->session->getId() : 0
432
        );
433
434
        return [
435
            'id' => $this->course->getId(),
436
            'title' => $this->course->getTitle(),
437
            'code' => $this->course->getCode(),
438
            'directory' => $this->course->getDirectory(),
439
            'urlPicture' => CourseManager::getPicturePath($this->course, true),
440
            'teachers' => $teachers,
441
            'tools' => array_map(
442
                function ($tool) {
443
                    return ['type' => $tool['name']];
444
                },
445
                $tools
446
            ),
447
        ];
448
    }
449
450
    /**
451
     * Get the course descriptions.
452
     *
453
     * @throws Exception
454
     *
455
     * @return array
456
     */
457
    public function getCourseDescriptions()
458
    {
459
        Event::event_access_tool(TOOL_COURSE_DESCRIPTION);
460
461
        $descriptions = CourseDescription::get_descriptions($this->course->getId());
462
        $results = [];
463
464
        $webPath = api_get_path(WEB_PATH);
465
466
        /** @var CourseDescription $description */
467
        foreach ($descriptions as $description) {
468
            $results[] = [
469
                'id' => $description->get_description_type(),
470
                'title' => $description->get_title(),
471
                'content' => str_replace('src="/', 'src="'.$webPath, $description->get_content()),
472
            ];
473
        }
474
475
        return $results;
476
    }
477
478
    /**
479
     * @param int $directoryId
480
     *
481
     * @throws Exception
482
     *
483
     * @return array
484
     */
485
    public function getCourseDocuments($directoryId = 0)
486
    {
487
        Event::event_access_tool(TOOL_DOCUMENT);
488
489
        /** @var string $path */
490
        $path = '/';
491
        $sessionId = $this->session ? $this->session->getId() : 0;
492
493
        if ($directoryId) {
494
            $directory = DocumentManager::get_document_data_by_id(
495
                $directoryId,
496
                $this->course->getCode(),
497
                false,
498
                $sessionId
499
            );
500
501
            if (!$directory) {
502
                throw new Exception('NoDataAvailable');
503
            }
504
505
            $path = $directory['path'];
506
        }
507
508
        $courseInfo = api_get_course_info_by_id($this->course->getId());
509
        $documents = DocumentManager::getAllDocumentData(
510
            $courseInfo,
511
            $path,
512
            0,
513
            null,
514
            false,
515
            false,
516
            $sessionId
517
        );
518
        $results = [];
519
520
        if (!empty($documents)) {
521
            $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
522
523
            /** @var array $document */
524
            foreach ($documents as $document) {
525
                if ($document['visibility'] != '1') {
526
                    continue;
527
                }
528
529
                $icon = $document['filetype'] == 'file'
530
                    ? choose_image($document['path'])
531
                    : chooseFolderIcon($document['path']);
532
533
                $results[] = [
534
                    'id' => $document['id'],
535
                    'type' => $document['filetype'],
536
                    'title' => $document['title'],
537
                    'path' => $document['path'],
538
                    'url' => $webPath.http_build_query(
539
                        [
540
                            'username' => $this->user->getUsername(),
541
                            'api_key' => $this->apiKey,
542
                            'cidReq' => $this->course->getCode(),
543
                            'id_session' => $sessionId,
544
                            'gidReq' => 0,
545
                            'gradebook' => 0,
546
                            'origin' => '',
547
                            'action' => 'download',
548
                            'id' => $document['id'],
549
                        ]
550
                    ),
551
                    'icon' => $icon,
552
                    'size' => format_file_size($document['size']),
553
                ];
554
            }
555
        }
556
557
        return $results;
558
    }
559
560
    /**
561
     * @throws Exception
562
     *
563
     * @return array
564
     */
565
    public function getCourseAnnouncements()
566
    {
567
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
568
569
        $sessionId = $this->session ? $this->session->getId() : 0;
570
571
        $announcements = AnnouncementManager::getAnnouncements(
572
            null,
573
            null,
574
            false,
575
            null,
576
            null,
577
            null,
578
            null,
579
            null,
580
            0,
581
            $this->user->getId(),
582
            $this->course->getId(),
583
            $sessionId
584
        );
585
586
        $announcements = array_map(
587
            function ($announcement) {
588
                return [
589
                    'id' => (int) $announcement['id'],
590
                    'title' => strip_tags($announcement['title']),
591
                    'creatorName' => strip_tags($announcement['username']),
592
                    'date' => strip_tags($announcement['insert_date']),
593
                ];
594
            },
595
            $announcements
596
        );
597
598
        return $announcements;
599
    }
600
601
    /**
602
     * @param int $announcementId
603
     *
604
     * @throws Exception
605
     *
606
     * @return array
607
     */
608
    public function getCourseAnnouncement($announcementId)
609
    {
610
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
611
612
        $sessionId = $this->session ? $this->session->getId() : 0;
613
        $announcement = AnnouncementManager::getAnnouncementInfoById(
614
            $announcementId,
615
            $this->course->getId(),
616
            $this->user->getId()
617
        );
618
619
        if (!$announcement) {
620
            throw new Exception(get_lang('NoAnnouncement'));
621
        }
622
623
        return [
624
            'id' => $announcement['announcement']->getIid(),
625
            'title' => $announcement['announcement']->getTitle(),
626
            'creatorName' => UserManager::formatUserFullName($announcement['item_property']->getInsertUser()),
627
            'date' => api_convert_and_format_date(
628
                $announcement['item_property']->getInsertDate(),
629
                DATE_TIME_FORMAT_LONG_24H
630
            ),
631
            'content' => AnnouncementManager::parseContent(
632
                $this->user->getId(),
633
                $announcement['announcement']->getContent(),
634
                $this->course->getCode(),
635
                $sessionId
636
            ),
637
        ];
638
    }
639
640
    /**
641
     * @throws Exception
642
     *
643
     * @return array
644
     */
645
    public function getCourseAgenda()
646
    {
647
        Event::event_access_tool(TOOL_CALENDAR_EVENT);
648
649
        $sessionId = $this->session ? $this->session->getId() : 0;
650
651
        $agenda = new Agenda(
652
            'course',
653
            $this->user->getId(),
654
            $this->course->getId(),
655
            $sessionId
656
        );
657
        $result = $agenda->parseAgendaFilter(null);
658
659
        $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
660
        $start->modify('first day of this month');
661
        $start->setTime(0, 0, 0);
662
        $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
663
        $end->modify('last day of this month');
664
        $end->setTime(23, 59, 59);
665
666
        $groupId = current($result['groups']);
667
        $userId = current($result['users']);
668
669
        $events = $agenda->getEvents(
670
            $start->getTimestamp(),
671
            $end->getTimestamp(),
672
            $this->course->getId(),
673
            $groupId,
674
            $userId,
675
            'array'
676
        );
677
678
        if (!is_array($events)) {
679
            return [];
680
        }
681
682
        $webPath = api_get_path(WEB_PATH);
683
684
        return array_map(
685
            function ($event) use ($webPath) {
686
                return [
687
                    'id' => (int) $event['unique_id'],
688
                    'title' => $event['title'],
689
                    'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
690
                    'startDate' => $event['start_date_localtime'],
691
                    'endDate' => $event['end_date_localtime'],
692
                    'isAllDay' => $event['allDay'] ? true : false,
693
                ];
694
            },
695
            $events
696
        );
697
    }
698
699
    /**
700
     * @throws Exception
701
     *
702
     * @return array
703
     */
704
    public function getCourseNotebooks()
705
    {
706
        Event::event_access_tool(TOOL_NOTEBOOK);
707
708
        $em = Database::getManager();
709
        /** @var CNotebookRepository $notebooksRepo */
710
        $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
711
        $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
712
713
        return array_map(
714
            function (CNotebook $notebook) {
715
                return [
716
                    'id' => $notebook->getIid(),
717
                    'title' => $notebook->getTitle(),
718
                    'description' => $notebook->getDescription(),
719
                    'creationDate' => api_format_date(
720
                        $notebook->getCreationDate()->getTimestamp()
721
                    ),
722
                    'updateDate' => api_format_date(
723
                        $notebook->getUpdateDate()->getTimestamp()
724
                    ),
725
                ];
726
            },
727
            $notebooks
728
        );
729
    }
730
731
    /**
732
     * @throws Exception
733
     *
734
     * @return array
735
     */
736
    public function getCourseForumCategories()
737
    {
738
        Event::event_access_tool(TOOL_FORUM);
739
740
        $sessionId = $this->session ? $this->session->getId() : 0;
741
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
742
743
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
744
745
        $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
746
        $categories = [];
747
        $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
748
        $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
749
        $forums = [];
750
751
        foreach ($forumsFullData as $forumId => $forumInfo) {
752
            $forum = [
753
                'id' => (int) $forumInfo['iid'],
754
                'catId' => (int) $forumInfo['forum_category'],
755
                'title' => $forumInfo['forum_title'],
756
                'description' => $forumInfo['forum_comment'],
757
                'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
758
                'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval(
759
                    $forumInfo['number_of_threads']
760
                ) : 0,
761
                'lastPost' => null,
762
            ];
763
764
            $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
765
766
            if ($lastPostInfo) {
767
                $forum['lastPost'] = [
768
                    'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
769
                    'user' => api_get_person_name(
770
                        $lastPostInfo['last_poster_firstname'],
771
                        $lastPostInfo['last_poster_lastname']
772
                    ),
773
                ];
774
            }
775
776
            $forums[] = $forum;
777
        }
778
779
        foreach ($categoriesFullData as $category) {
780
            $categoryForums = array_filter(
781
                $forums,
782
                function (array $forum) use ($category) {
783
                    if ($forum['catId'] != $category['cat_id']) {
784
                        return false;
785
                    }
786
787
                    return true;
788
                }
789
            );
790
791
            $categories[] = [
792
                'id' => (int) $category['iid'],
793
                'title' => $category['cat_title'],
794
                'catId' => (int) $category['cat_id'],
795
                'description' => $category['cat_comment'],
796
                'forums' => $categoryForums,
797
                'courseId' => $this->course->getId(),
798
            ];
799
        }
800
801
        return $categories;
802
    }
803
804
    /**
805
     * @param int $forumId
806
     *
807
     * @throws Exception
808
     *
809
     * @return array
810
     */
811
    public function getCourseForum($forumId)
812
    {
813
        Event::event_access_tool(TOOL_FORUM);
814
815
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
816
817
        $sessionId = $this->session ? $this->session->getId() : 0;
818
        $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
819
820
        if (!isset($forumInfo['iid'])) {
821
            throw new Exception(get_lang('NoForum'));
822
        }
823
824
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
825
        $forum = [
826
            'id' => $forumInfo['iid'],
827
            'title' => $forumInfo['forum_title'],
828
            'description' => $forumInfo['forum_comment'],
829
            'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
830
            'threads' => [],
831
        ];
832
833
        $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
834
835
        foreach ($threads as $thread) {
836
            $forum['threads'][] = [
837
                'id' => $thread['iid'],
838
                'title' => $thread['thread_title'],
839
                'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
840
                'numberOfReplies' => $thread['thread_replies'],
841
                'numberOfViews' => $thread['thread_views'],
842
                'author' => api_get_person_name($thread['firstname'], $thread['lastname']),
843
            ];
844
        }
845
846
        return $forum;
847
    }
848
849
    /**
850
     * @param int $forumId
851
     * @param int $threadId
852
     *
853
     * @return array
854
     */
855
    public function getCourseForumThread($forumId, $threadId)
856
    {
857
        Event::event_access_tool(TOOL_FORUM);
858
859
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
860
861
        $sessionId = $this->session ? $this->session->getId() : 0;
862
        $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
863
864
        $thread = [
865
            'id' => intval($threadInfo['iid']),
866
            'cId' => intval($threadInfo['c_id']),
867
            'title' => $threadInfo['thread_title'],
868
            'forumId' => intval($threadInfo['forum_id']),
869
            'posts' => [],
870
        ];
871
872
        $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
873
        $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
874
875
        foreach ($postsInfo as $postInfo) {
876
            $thread['posts'][] = [
877
                'id' => $postInfo['iid'],
878
                'title' => $postInfo['post_title'],
879
                'text' => $postInfo['post_text'],
880
                'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
881
                'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
882
                'parentId' => $postInfo['post_parent_id'],
883
                'attachments' => getAttachedFiles(
884
                    $forumId,
885
                    $threadId,
886
                    $postInfo['iid'],
887
                    0,
888
                    $this->course->getId()
889
                )
890
            ];
891
        }
892
893
        return $thread;
894
    }
895
896
    public function getCourseLinks(): array
897
    {
898
        Event::event_access_tool(TOOL_LINK);
899
900
        $courseId = $this->course->getId();
901
        $sessionId = $this->session ? $this->session->getId() : 0;
902
903
        $webCodePath = api_get_path(WEB_CODE_PATH);
904
        $cidReq = api_get_cidreq();
905
906
        $categories = array_merge(
907
            [
908
                [
909
                    'iid' => 0,
910
                    'c_id' => $courseId,
911
                    'id' => 0,
912
                    'category_title' => get_lang('NoCategory'),
913
                    'description' => '',
914
                    'display_order' => 0,
915
                    'session_id' => $sessionId,
916
                    'visibility' => 1,
917
                ],
918
            ],
919
            Link::getLinkCategories($courseId, $sessionId)
920
        );
921
922
        $categories = array_filter(
923
            $categories,
924
            function (array $category) {
925
                return $category['visibility'] != 0;
926
            }
927
        );
928
929
        return array_map(
930
            function (array $category) use ($webCodePath, $cidReq, $courseId, $sessionId) {
931
                $links = array_filter(
932
                    Link::getLinksPerCategory($category['iid'], $courseId, $sessionId),
933
                    function (array $link) {
934
                        return $link['visibility'] != 0;
935
                    }
936
                );
937
938
                $links = array_map(
939
                    function (array $link) use ($webCodePath, $cidReq) {
940
                        return [
941
                            'id' => (int) $link['id'],
942
                            'title' => Security::remove_XSS($link['title']),
943
                            'description' => Security::remove_XSS($link['description']),
944
                            'visibility' => (int) $link['visibility'],
945
                            'url' => $webCodePath."link/link_goto.php?$cidReq&link_id=".$link['id'],
946
                        ];
947
                    },
948
                    $links
949
                );
950
951
                return [
952
                    'id' => (int) $category['iid'],
953
                    'title' => Security::remove_XSS($category['category_title']),
954
                    'description' => Security::remove_XSS($category['description']),
955
                    'visibility' => (int) $category['visibility'],
956
                    'links' => $links,
957
                ];
958
            },
959
            $categories
960
        );
961
    }
962
963
    /**
964
     * @return array
965
     */
966
    public function getUserProfile()
967
    {
968
        $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
969
970
        $result = [
971
            'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
972
            'id' => $this->user->getId(),
973
            'status' => $this->user->getStatus(),
974
            'fullName' => UserManager::formatUserFullName($this->user),
975
            'username' => $this->user->getUsername(),
976
            'officialCode' => $this->user->getOfficialCode(),
977
            'phone' => $this->user->getPhone(),
978
            'extra' => [],
979
        ];
980
981
        $fieldValue = new ExtraFieldValue('user');
982
        $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
983
984
        foreach ($extraInfo as $extra) {
985
            /** @var ExtraFieldValues $extraValue */
986
            $extraValue = $extra['value'];
987
            $result['extra'][] = [
988
                'title' => $extraValue->getField()->getDisplayText(true),
989
                'value' => $extraValue->getValue(),
990
            ];
991
        }
992
993
        return $result;
994
    }
995
996
    public function getCourseLpProgress()
997
    {
998
        $sessionId = $this->session ? $this->session->getId() : 0;
999
        $userId = $this->user->getId();
1000
1001
        /*$sessionId = $this->session ? $this->session->getId() : 0;
1002
        $courseId = $this->course->getId();*/
1003
1004
        $result = Tracking::getCourseLpProgress($userId, $sessionId);
1005
1006
        return [$result];
1007
    }
1008
1009
    /**
1010
     * @throws Exception
1011
     *
1012
     * @return array
1013
     */
1014
    public function getCourseLearnPaths()
1015
    {
1016
        Event::event_access_tool(TOOL_LEARNPATH);
1017
1018
        $sessionId = $this->session ? $this->session->getId() : 0;
1019
        $categoriesTempList = learnpath::getCategories($this->course->getId());
1020
1021
        $categoryNone = new CLpCategory();
1022
        $categoryNone->setId(0);
1023
        $categoryNone->setName(get_lang('WithOutCategory'));
1024
        $categoryNone->setPosition(0);
1025
1026
        $categories = array_merge([$categoryNone], $categoriesTempList);
1027
        $categoryData = [];
1028
1029
        /** @var CLpCategory $category */
1030
        foreach ($categories as $category) {
1031
            $learnPathList = new LearnpathList(
1032
                $this->user->getId(),
1033
                api_get_course_info($this->course->getCode()),
1034
                $sessionId,
1035
                null,
1036
                false,
1037
                $category->getId()
1038
            );
1039
1040
            $flatLpList = $learnPathList->get_flat_list();
1041
1042
            if (empty($flatLpList)) {
1043
                continue;
1044
            }
1045
1046
            $listData = [];
1047
1048
            foreach ($flatLpList as $lpId => $lpDetails) {
1049
                if ($lpDetails['lp_visibility'] == 0) {
1050
                    continue;
1051
                }
1052
1053
                if (!learnpath::is_lp_visible_for_student(
1054
                    $lpId,
1055
                    $this->user->getId(),
1056
                    api_get_course_info($this->course->getCode()),
1057
                    $sessionId
1058
                )) {
1059
                    continue;
1060
                }
1061
1062
                $timeLimits = false;
1063
1064
                // This is an old LP (from a migration 1.8.7) so we do nothing
1065
                if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
1066
                    $timeLimits = false;
1067
                }
1068
1069
                // Checking if expired_on is ON
1070
                if (!empty($lpDetails['expired_on'])) {
1071
                    $timeLimits = true;
1072
                }
1073
1074
                if ($timeLimits) {
1075
                    if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
1076
                        $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
1077
                        $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
1078
                        $now = time();
1079
                        $isActiveTime = false;
1080
1081
                        if ($now > $startTime && $endTime > $now) {
1082
                            $isActiveTime = true;
1083
                        }
1084
1085
                        if (!$isActiveTime) {
1086
                            continue;
1087
                        }
1088
                    }
1089
                }
1090
1091
                $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
1092
1093
                $listData[] = [
1094
                    'id' => $lpId,
1095
                    'title' => Security::remove_XSS($lpDetails['lp_name']),
1096
                    'progress' => $progress,
1097
                    'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query(
1098
                        [
1099
                            'hash' => $this->encodeParams(
1100
                                [
1101
                                    'action' => 'course_learnpath',
1102
                                    'lp_id' => $lpId,
1103
                                    'course' => $this->course->getId(),
1104
                                    'session' => $sessionId,
1105
                                ]
1106
                            ),
1107
                        ]
1108
                    ),
1109
                ];
1110
            }
1111
1112
            if (empty($listData)) {
1113
                continue;
1114
            }
1115
1116
            $categoryData[] = [
1117
                'id' => $category->getId(),
1118
                'name' => $category->getName(),
1119
                'learnpaths' => $listData,
1120
            ];
1121
        }
1122
1123
        return $categoryData;
1124
    }
1125
1126
    /**
1127
     * Start login for a user. Then make a redirect to show the learnpath.
1128
     *
1129
     * @param int $lpId
1130
     */
1131
    public function showLearningPath($lpId)
1132
    {
1133
        $loggedUser['user_id'] = $this->user->getId();
1134
        $loggedUser['status'] = $this->user->getStatus();
1135
        $loggedUser['uidReset'] = true;
1136
        $sessionId = $this->session ? $this->session->getId() : 0;
1137
1138
        ChamiloSession::write('_user', $loggedUser);
1139
        Login::init_user($this->user->getId(), true);
1140
1141
        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query(
1142
            [
1143
                'cidReq' => $this->course->getCode(),
1144
                'id_session' => $sessionId,
1145
                'gidReq' => 0,
1146
                'gradebook' => 0,
1147
                'origin' => '',
1148
                'action' => 'view',
1149
                'lp_id' => (int) $lpId,
1150
                'isStudentView' => 'true',
1151
            ]
1152
        );
1153
1154
        header("Location: $url");
1155
        exit;
1156
    }
1157
1158
    /**
1159
     * @param int $forumId
1160
     *
1161
     * @return array
1162
     */
1163
    public function saveForumPost(array $postValues, $forumId)
1164
    {
1165
        Event::event_access_tool(TOOL_FORUM);
1166
1167
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1168
1169
        $forum = get_forums($forumId, $this->course->getCode());
1170
        store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
1171
1172
        return [
1173
            'registered' => true,
1174
        ];
1175
    }
1176
1177
    /**
1178
     * Get the list of sessions for current user.
1179
     *
1180
     * @return array the sessions list
1181
     */