Passed
Push — 1.11.x ( 655124...47465b )
by Angel Fernando Quiroz
14:14
created

Rest::downloadWork()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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