Passed
Push — 1.11.x ( 955bb6...baa1d9 )
by Angel Fernando Quiroz
08:50
created

Rest::getUserApiKey()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 11
c 1
b 0
f 0
dl 0
loc 20
rs 9.6111
cc 5
nc 4
nop 1
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
use Symfony\Component\HttpFoundation\Request as HttpRequest;
13
14
/**
15
 * Class RestApi.
16
 */
17
class Rest extends WebService
18
{
19
    const SERVICE_NAME = 'MsgREST';
20
    const EXTRA_FIELD_GCM_REGISTRATION = 'gcm_registration_id';
21
22
    const GET_AUTH = 'authenticate';
23
    const SAVE_GCM_ID = 'gcm_id';
24
    const LOGOUT = 'logout';
25
26
    const GET_USER_MESSAGES = 'user_messages';
27
    const GET_USER_MESSAGES_RECEIVED = 'user_messages_received';
28
    const DELETE_USER_MESSAGE = 'delete_user_message';
29
    const GET_USER_MESSAGES_SENT = 'user_messages_sent';
30
    const GET_COUNT_NEW_MESSAGES = 'get_count_new_messages';
31
    const SET_MESSAGE_READ = 'set_message_read';
32
    const POST_USER_MESSAGE_READ = 'user_message_read';
33
    const POST_USER_MESSAGE_UNREAD = 'user_message_unread';
34
    const SAVE_USER_MESSAGE = 'save_user_message';
35
    const GET_MESSAGE_USERS = 'message_users';
36
    const VIEW_MESSAGE = 'view_message';
37
38
    const GET_USER_COURSES = 'user_courses';
39
    const GET_USER_SESSIONS = 'user_sessions';
40
41
    const VIEW_PROFILE = 'view_user_profile';
42
    const GET_PROFILE = 'user_profile';
43
44
    const VIEW_COURSE_HOME = 'view_course_home';
45
    const GET_COURSE_INFO = 'course_info';
46
    const GET_COURSE_DESCRIPTIONS = 'course_descriptions';
47
    const GET_COURSE_DOCUMENTS = 'course_documents';
48
    const GET_COURSE_ANNOUNCEMENTS = 'course_announcements';
49
    const GET_COURSE_ANNOUNCEMENT = 'course_announcement';
50
    const GET_COURSE_AGENDA = 'course_agenda';
51
    const GET_COURSE_NOTEBOOKS = 'course_notebooks';
52
    const GET_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
53
    const GET_COURSE_FORUM = 'course_forum';
54
    const GET_COURSE_FORUM_THREAD = 'course_forumthread';
55
    const GET_COURSE_LEARNPATHS = 'course_learnpaths';
56
    const GET_COURSE_LEARNPATH = 'course_learnpath';
57
    const GET_COURSE_LP_PROGRESS = 'course_lp_progress';
58
    const GET_COURSE_LINKS = 'course_links';
59
    const GET_COURSE_WORKS = 'course_works';
60
61
    const SAVE_COURSE_NOTEBOOK = 'save_course_notebook';
62
63
    const SAVE_FORUM_POST = 'save_forum_post';
64
    const SAVE_FORUM_THREAD = 'save_forum_thread';
65
    const SET_THREAD_NOTIFY = 'set_thread_notify';
66
    const DOWNLOAD_FORUM_ATTACHMENT = 'download_forum_attachment';
67
68
    const GET_WORK_LIST = 'get_work_list';
69
    const GET_WORK_STUDENTS_WITHOUT_PUBLICATIONS = 'get_work_students_without_publications';
70
    const GET_WORK_USERS = 'get_work_users';
71
    const GET_WORK_STUDENT_LIST = 'get_work_student_list';
72
    const PUT_WORK_STUDENT_ITEM_VISIBILITY = 'put_course_work_visibility';
73
    const DELETE_WORK_STUDENT_ITEM = 'delete_work_student_item';
74
    const DELETE_WORK_CORRECTIONS = 'delete_work_corrections';
75
    const DOWNLOAD_WORK_FOLDER = 'download_work_folder';
76
    const DOWNLOAD_WORK_COMMENT_ATTACHMENT = 'download_work_comment_attachment';
77
    const DOWNLOAD_WORK = 'download_work';
78
79
    const VIEW_DOCUMENT_IN_FRAME = 'view_document_in_frame';
80
81
    const VIEW_QUIZ_TOOL = 'view_quiz_tool';
82
83
    const VIEW_SURVEY_TOOL = 'view_survey_tool';
84
85
    const CREATE_CAMPUS = 'add_campus';
86
    const EDIT_CAMPUS = 'edit_campus';
87
    const DELETE_CAMPUS = 'delete_campus';
88
89
    const GET_USERS = 'get_users';
90
    const USERNAME_EXIST = 'username_exist';
91
    const SAVE_USER = 'save_user';
92
    const SAVE_USER_GET_APIKEY = 'save_user_get_apikey';
93
    const SAVE_USER_JSON = 'save_user_json';
94
    const UPDATE_USER_FROM_USERNAME = 'update_user_from_username';
95
    const UPDATE_USER_APIKEY = 'update_user_apikey';
96
    const DELETE_USER = 'delete_user';
97
    const GET_USERS_API_KEYS = 'get_users_api_keys';
98
    const GET_USER_API_KEY = 'get_user_api_key';
99
100
    const GET_COURSES = 'get_courses';
101
    const GET_COURSES_FROM_EXTRA_FIELD = 'get_courses_from_extra_field';
102
    const SAVE_COURSE = 'save_course';
103
    const DELETE_COURSE = 'delete_course';
104
105
    const GET_SESSION_FROM_EXTRA_FIELD = 'get_session_from_extra_field';
106
    const SAVE_SESSION = 'save_session';
107
    const CREATE_SESSION_FROM_MODEL = 'create_session_from_model';
108
    const UPDATE_SESSION = 'update_session';
109
110
    const SUBSCRIBE_USER_TO_COURSE = 'subscribe_user_to_course';
111
    const SUBSCRIBE_USER_TO_COURSE_PASSWORD = 'subscribe_user_to_course_password';
112
    const UNSUBSCRIBE_USER_FROM_COURSE = 'unsubscribe_user_from_course';
113
    const GET_USERS_SUBSCRIBED_TO_COURSE = 'get_users_subscribed_to_course';
114
115
    const ADD_COURSES_SESSION = 'add_courses_session';
116
    const ADD_USERS_SESSION = 'add_users_session';
117
    const SUBSCRIBE_USER_TO_SESSION_FROM_USERNAME = 'subscribe_user_to_session_from_username';
118
119
    const GET_COURSE_QUIZ_MDL_COMPAT = 'get_course_quiz_mdl_compat';
120
121
    const UPDATE_USER_PAUSE_TRAINING = 'update_user_pause_training';
122
123
    const CHECK_CONDITIONAL_LOGIN = 'check_conditional_login';
124
    const GET_LEGAL_CONDITIONS = 'get_legal_conditions';
125
    const UPDATE_CONDITION_ACCEPTED = 'update_condition_accepted';
126
127
    /**
128
     * @var Session
129
     */
130
    private $session;
131
132
    /**
133
     * @var Course
134
     */
135
    private $course;
136
137
    /**
138
     * Rest constructor.
139
     *
140
     * @param string $username
141
     * @param string $apiKey
142
     */
143
    public function __construct($username, $apiKey)
144
    {
145
        parent::__construct($username, $apiKey);
146
    }
147
148
    /**
149
     * @param string $username
150
     * @param string $apiKeyToValidate
151
     *
152
     * @throws Exception
153
     *
154
     * @return Rest
155
     */
156
    public static function validate($username, $apiKeyToValidate)
157
    {
158
        $apiKey = self::findUserApiKey($username, self::SERVICE_NAME);
159
160
        if ($apiKey != $apiKeyToValidate) {
161
            throw new Exception(get_lang('InvalidApiKey'));
162
        }
163
164
        return new self($username, $apiKey);
165
    }
166
167
    /**
168
     * Create the gcm_registration_id extra field for users.
169
     */
170
    public static function init()
171
    {
172
        $extraField = new ExtraField('user');
173
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
174
175
        if (empty($fieldInfo)) {
176
            $extraField->save(
177
                [
178
                    'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
179
                    'field_type' => ExtraField::FIELD_TYPE_TEXT,
180
                    'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION,
181
                ]
182
            );
183
        }
184
    }
185
186
    /**
187
     * @param string $encoded
188
     *
189
     * @return array
190
     */
191
    public static function decodeParams($encoded)
192
    {
193
        return json_decode($encoded);
194
    }
195
196
    /**
197
     * Set the current course.
198
     *
199
     * @param int $id
200
     *
201
     * @throws Exception
202
     */
203
    public function setCourse($id)
204
    {
205
        global $_course;
206
207
        if (!$id) {
208
            $this->course = null;
209
210
            ChamiloSession::erase('_real_cid');
211
            ChamiloSession::erase('_cid');
212
            ChamiloSession::erase('_course');
213
214
            return;
215
        }
216
217
        $em = Database::getManager();
218
        /** @var Course $course */
219
        $course = $em->find('ChamiloCoreBundle:Course', $id);
220
221
        if (!$course) {
0 ignored issues
show
introduced by
$course is of type Chamilo\CoreBundle\Entity\Course, thus it always evaluated to true.
Loading history...
222
            throw new Exception(get_lang('NoCourse'));
223
        }
224
225
        $this->course = $course;
226
227
        $courseInfo = api_get_course_info($course->getCode());
228
        $_course = $courseInfo;
229
230
        ChamiloSession::write('_real_cid', $course->getId());
231
        ChamiloSession::write('_cid', $course->getCode());
232
        ChamiloSession::write('_course', $courseInfo);
233
    }
234
235
    /**
236
     * Set the current session.
237
     *
238
     * @param int $id
239
     *
240
     * @throws Exception
241
     */
242
    public function setSession($id)
243
    {
244
        if (!$id) {
245
            $this->session = null;
246
247
            ChamiloSession::erase('session_name');
248
            ChamiloSession::erase('id_session');
249
250
            return;
251
        }
252
253
        $em = Database::getManager();
254
        /** @var Session $session */
255
        $session = $em->find('ChamiloCoreBundle:Session', $id);
256
257
        if (!$session) {
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
258
            throw new Exception(get_lang('NoSession'));
259
        }
260
261
        $this->session = $session;
262
263
        ChamiloSession::write('session_name', $session->getName());
264
        ChamiloSession::write('id_session', $session->getId());
265
    }
266
267
    /**
268
     * @param string $registrationId
269
     *
270
     * @return bool
271
     */
272
    public function setGcmId($registrationId)
273
    {
274
        $registrationId = Security::remove_XSS($registrationId);
275
        $extraFieldValue = new ExtraFieldValue('user');
276
277
        return $extraFieldValue->save(
278
            [
279
                'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
280
                'value' => $registrationId,
281
                'item_id' => $this->user->getId(),
282
            ]
283
        );
284
    }
285
286
    /**
287
     * @param int $lastMessageId
288
     *
289
     * @return array
290
     */
291
    public function getUserMessages($lastMessageId = 0)
292
    {
293
        $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
294
        $messages = [];
295
296
        foreach ($lastMessages as $message) {
297
            $hasAttachments = MessageManager::hasAttachments($message['id']);
298
299
            $messages[] = [
300
                'id' => $message['id'],
301
                'title' => $message['title'],
302
                'sender' => [
303
                    'id' => $message['user_id'],
304
                    'lastname' => $message['lastname'],
305
                    'firstname' => $message['firstname'],
306
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
307
                ],
308
                'sendDate' => $message['send_date'],
309
                'content' => $message['content'],
310
                'hasAttachments' => $hasAttachments,
311
                'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?'
312
                    .http_build_query(['type' => 1, 'id' => $message['id']]),
313
            ];
314
        }
315
316
        return $messages;
317
    }
318
319
    /**
320
     * @return array
321
     */
322
    public function getUserReceivedMessages()
323
    {
324
        $lastMessages = MessageManager::getReceivedMessages($this->user->getId(), 0);
325
        $messages = [];
326
327
        $webPath = api_get_path(WEB_PATH);
328
329
        foreach ($lastMessages as $message) {
330
            $hasAttachments = MessageManager::hasAttachments($message['id']);
331
            $attachmentList = [];
332
            if ($hasAttachments) {
333
                $attachmentList = MessageManager::getAttachmentList($message['id']);
334
            }
335
            $messages[] = [
336
                'id' => $message['id'],
337
                'title' => $message['title'],
338
                'msgStatus' => $message['msg_status'],
339
                'sender' => [
340
                    'id' => $message['user_id'],
341
                    'lastname' => $message['lastname'],
342
                    'firstname' => $message['firstname'],
343
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
344
                    'pictureUri' => $message['pictureUri'],
345
                ],
346
                'sendDate' => $message['send_date'],
347
                'content' => str_replace('src="/"', $webPath, $message['content']),
348
                'hasAttachments' => $hasAttachments,
349
                'attachmentList' => $attachmentList,
350
                'url' => '',
351
            ];
352
        }
353
354
        return $messages;
355
    }
356
357
    /**
358
     * @return array
359
     */
360
    public function getUserSentMessages()
361
    {
362
        $lastMessages = MessageManager::getSentMessages($this->user->getId(), 0);
363
        $messages = [];
364
365
        foreach ($lastMessages as $message) {
366
            $hasAttachments = MessageManager::hasAttachments($message['id']);
367
368
            $messages[] = [
369
                'id' => $message['id'],
370
                'title' => $message['title'],
371
                'msgStatus' => $message['msg_status'],
372
                'receiver' => [
373
                    'id' => $message['user_id'],
374
                    'lastname' => $message['lastname'],
375
                    'firstname' => $message['firstname'],
376
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
377
                    'pictureUri' => $message['pictureUri'],
378
                ],
379
                'sendDate' => $message['send_date'],
380
                'content' => $message['content'],
381
                'hasAttachments' => $hasAttachments,
382
                'url' => '',
383
            ];
384
        }
385
386
        return $messages;
387
    }
388
389
    /**
390
     * Get the user courses.
391
     */
392
    public function getUserCourses($userId = 0): array
393
    {
394
        if (empty($userId)) {
395
            $userId = $this->user->getId();
396
        }
397
398
        Event::courseLogout(
399
            [
400
                'uid' => $userId,
401
                'cid' => api_get_course_id(),
402
                'sid' => api_get_session_id(),
403
            ]
404
        );
405
406
        $courses = CourseManager::get_courses_list_by_user_id($userId);
407
        $data = [];
408
409
        $webCodePath = api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?';
410
411
        foreach ($courses as $courseInfo) {
412
            /** @var Course $course */
413
            $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseInfo['real_id']);
414
            $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode());
415
            $picturePath = CourseManager::getPicturePath($course, true)
416
                ?: Display::return_icon('session_default.png', null, null, null, null, true);
417
418
            $data[] = [
419
                'id' => $course->getId(),
420
                'title' => $course->getTitle(),
421
                'code' => $course->getCode(),
422
                'directory' => $course->getDirectory(),
423
                'urlPicture' => $picturePath,
424
                'teachers' => $teachers,
425
                'isSpecial' => !empty($courseInfo['special_course']),
426
                'url' => $webCodePath.http_build_query(
427
                    [
428
                        'action' => self::VIEW_COURSE_HOME,
429
                        'api_key' => $this->apiKey,
430
                        'username' => $this->user->getUsername(),
431
                        'course' => $course->getId(),
432
                    ]
433
                ),
434
            ];
435
        }
436
437
        return $data;
438
    }
439
440
    /**
441
     * @throws Exception
442
     *
443
     * @return array
444
     */
445
    public function getCourseInfo()
446
    {
447
        $teachers = CourseManager::getTeacherListFromCourseCodeToString($this->course->getCode());
448
        $tools = CourseHome::get_tools_category(
449
            TOOL_STUDENT_VIEW,
450
            $this->course->getId(),
451
            $this->session ? $this->session->getId() : 0
452
        );
453
454
        return [
455
            'id' => $this->course->getId(),
456
            'title' => $this->course->getTitle(),
457
            'code' => $this->course->getCode(),
458
            'directory' => $this->course->getDirectory(),
459
            'urlPicture' => CourseManager::getPicturePath($this->course, true),
460
            'teachers' => $teachers,
461
            'tools' => array_map(
462
                function ($tool) {
463
                    return ['type' => $tool['name']];
464
                },
465
                $tools
466
            ),
467
        ];
468
    }
469
470
    /**
471
     * Get the course descriptions.
472
     *
473
     * @throws Exception
474
     *
475
     * @return array
476
     */
477
    public function getCourseDescriptions()
478
    {
479
        Event::event_access_tool(TOOL_COURSE_DESCRIPTION);
480
481
        $descriptions = CourseDescription::get_descriptions($this->course->getId());
482
        $results = [];
483
484
        $webPath = api_get_path(WEB_PATH);
485
486
        /** @var CourseDescription $description */
487
        foreach ($descriptions as $description) {
488
            $results[] = [
489
                'id' => $description->get_description_type(),
490
                'title' => $description->get_title(),
491
                'content' => str_replace('src="/', 'src="'.$webPath, $description->get_content()),
492
            ];
493
        }
494
495
        return $results;
496
    }
497
498
    /**
499
     * @param int $directoryId
500
     *
501
     * @throws Exception
502
     *
503
     * @return array
504
     */
505
    public function getCourseDocuments($directoryId = 0)
506
    {
507
        Event::event_access_tool(TOOL_DOCUMENT);
508
509
        /** @var string $path */
510
        $path = '/';
511
        $sessionId = $this->session ? $this->session->getId() : 0;
512
513
        if ($directoryId) {
514
            $directory = DocumentManager::get_document_data_by_id(
515
                $directoryId,
516
                $this->course->getCode(),
517
                false,
518
                $sessionId
519
            );
520
521
            if (!$directory) {
522
                throw new Exception('NoDataAvailable');
523
            }
524
525
            $path = $directory['path'];
526
        }
527
528
        $courseInfo = api_get_course_info_by_id($this->course->getId());
529
        $documents = DocumentManager::getAllDocumentData(
530
            $courseInfo,
531
            $path,
532
            0,
533
            null,
534
            false,
535
            false,
536
            $sessionId
537
        );
538
        $results = [];
539
540
        if (!empty($documents)) {
541
            $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
542
543
            /** @var array $document */
544
            foreach ($documents as $document) {
545
                if ($document['visibility'] != '1') {
546
                    continue;
547
                }
548
549
                $icon = $document['filetype'] == 'file'
550
                    ? choose_image($document['path'])
551
                    : chooseFolderIcon($document['path']);
552
553
                $results[] = [
554
                    'id' => $document['id'],
555
                    'type' => $document['filetype'],
556
                    'title' => $document['title'],
557
                    'path' => $document['path'],
558
                    'url' => $webPath.http_build_query(
559
                        [
560
                            'username' => $this->user->getUsername(),
561
                            'api_key' => $this->apiKey,
562
                            'cidReq' => $this->course->getCode(),
563
                            'id_session' => $sessionId,
564
                            'gidReq' => 0,
565
                            'gradebook' => 0,
566
                            'origin' => '',
567
                            'action' => 'download',
568
                            'id' => $document['id'],
569
                        ]
570
                    ),
571
                    'icon' => $icon,
572
                    'size' => format_file_size($document['size']),
573
                ];
574
            }
575
        }
576
577
        return $results;
578
    }
579
580
    /**
581
     * @throws Exception
582
     *
583
     * @return array
584
     */
585
    public function getCourseAnnouncements()
586
    {
587
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
588
589
        $sessionId = $this->session ? $this->session->getId() : 0;
590
591
        $announcements = AnnouncementManager::getAnnouncements(
592
            null,
593
            null,
594
            false,
595
            null,
596
            null,
597
            null,
598
            null,
599
            null,
600
            0,
601
            $this->user->getId(),
602
            $this->course->getId(),
603
            $sessionId
604
        );
605
606
        $announcements = array_map(
607
            function ($announcement) {
608
                return [
609
                    'id' => (int) $announcement['id'],
610
                    'title' => strip_tags($announcement['title']),
611
                    'creatorName' => strip_tags($announcement['username']),
612
                    'date' => strip_tags($announcement['insert_date']),
613
                ];
614
            },
615
            $announcements
616
        );
617
618
        return $announcements;
619
    }
620
621
    /**
622
     * @param int $announcementId
623
     *
624
     * @throws Exception
625
     *
626
     * @return array
627
     */
628
    public function getCourseAnnouncement($announcementId)
629
    {
630
        Event::event_access_tool(TOOL_ANNOUNCEMENT);
631
632
        $sessionId = $this->session ? $this->session->getId() : 0;
633
        $announcement = AnnouncementManager::getAnnouncementInfoById(
634
            $announcementId,
635
            $this->course->getId(),
636
            $this->user->getId()
637
        );
638
639
        if (!$announcement) {
640
            throw new Exception(get_lang('NoAnnouncement'));
641
        }
642
643
        return [
644
            'id' => $announcement['announcement']->getIid(),
645
            'title' => $announcement['announcement']->getTitle(),
646
            'creatorName' => UserManager::formatUserFullName($announcement['item_property']->getInsertUser()),
647
            'date' => api_convert_and_format_date(
648
                $announcement['item_property']->getInsertDate(),
649
                DATE_TIME_FORMAT_LONG_24H
650
            ),
651
            'content' => AnnouncementManager::parseContent(
652
                $this->user->getId(),
653
                $announcement['announcement']->getContent(),
654
                $this->course->getCode(),
655
                $sessionId
656
            ),
657
        ];
658
    }
659
660
    /**
661
     * @throws Exception
662
     *
663
     * @return array
664
     */
665
    public function getCourseAgenda()
666
    {
667
        Event::event_access_tool(TOOL_CALENDAR_EVENT);
668
669
        $sessionId = $this->session ? $this->session->getId() : 0;
670
671
        $agenda = new Agenda(
672
            'course',
673
            $this->user->getId(),
674
            $this->course->getId(),
675
            $sessionId
676
        );
677
        $result = $agenda->parseAgendaFilter(null);
678
679
        $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
680
        $start->modify('first day of this month');
681
        $start->setTime(0, 0, 0);
682
        $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
683
        $end->modify('last day of this month');
684
        $end->setTime(23, 59, 59);
685
686
        $groupId = current($result['groups']);
687
        $userId = current($result['users']);
688
689
        $events = $agenda->getEvents(
690
            $start->getTimestamp(),
691
            $end->getTimestamp(),
692
            $this->course->getId(),
693
            $groupId,
694
            $userId,
695
            'array'
696
        );
697
698
        if (!is_array($events)) {
699
            return [];
700
        }
701
702
        $webPath = api_get_path(WEB_PATH);
703
704
        return array_map(
705
            function ($event) use ($webPath) {
706
                return [
707
                    'id' => (int) $event['unique_id'],
708
                    'title' => $event['title'],
709
                    'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
710
                    'startDate' => $event['start_date_localtime'],
711
                    'endDate' => $event['end_date_localtime'],
712
                    'isAllDay' => $event['allDay'] ? true : false,
713
                ];
714
            },
715
            $events
716
        );
717
    }
718
719
    /**
720
     * @throws Exception
721
     *
722
     * @return array
723
     */
724
    public function getCourseNotebooks()
725
    {
726
        Event::event_access_tool(TOOL_NOTEBOOK);
727
728
        $em = Database::getManager();
729
        /** @var CNotebookRepository $notebooksRepo */
730
        $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
731
        $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
732
733
        return array_map(
734
            function (CNotebook $notebook) {
735
                return [
736
                    'id' => $notebook->getIid(),
737
                    'title' => $notebook->getTitle(),
738
                    'description' => $notebook->getDescription(),
739
                    'creationDate' => api_format_date(
740
                        $notebook->getCreationDate()->getTimestamp()
741
                    ),
742
                    'updateDate' => api_format_date(
743
                        $notebook->getUpdateDate()->getTimestamp()
744
                    ),
745
                ];
746
            },
747
            $notebooks
748
        );
749
    }
750
751
    /**
752
     * @throws Exception
753
     *
754
     * @return array
755
     */
756
    public function getCourseForumCategories()
757
    {
758
        Event::event_access_tool(TOOL_FORUM);
759
760
        $sessionId = $this->session ? $this->session->getId() : 0;
761
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
762
763
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
764
765
        $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
766
        $categories = [];
767
        $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
768
        $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
769
        $forums = [];
770
771
        foreach ($forumsFullData as $forumId => $forumInfo) {
772
            $forum = [
773
                'id' => (int) $forumInfo['iid'],
774
                'catId' => (int) $forumInfo['forum_category'],
775
                'title' => $forumInfo['forum_title'],
776
                'description' => $forumInfo['forum_comment'],
777
                'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
778
                'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval(
779
                    $forumInfo['number_of_threads']
780
                ) : 0,
781
                'lastPost' => null,
782
            ];
783
784
            $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
785
786
            if ($lastPostInfo) {
787
                $forum['lastPost'] = [
788
                    'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
789
                    'user' => api_get_person_name(
790
                        $lastPostInfo['last_poster_firstname'],
791
                        $lastPostInfo['last_poster_lastname']
792
                    ),
793
                ];
794
            }
795
796
            $forums[] = $forum;
797
        }
798
799
        foreach ($categoriesFullData as $category) {
800
            $categoryForums = array_filter(
801
                $forums,
802
                function (array $forum) use ($category) {
803
                    if ($forum['catId'] != $category['cat_id']) {
804
                        return false;
805
                    }
806
807
                    return true;
808
                }
809
            );
810
811
            $categories[] = [
812
                'id' => (int) $category['iid'],
813
                'title' => $category['cat_title'],
814
                'catId' => (int) $category['cat_id'],
815
                'description' => $category['cat_comment'],
816
                'forums' => $categoryForums,
817
                'courseId' => $this->course->getId(),
818
            ];
819
        }
820
821
        return $categories;
822
    }
823
824
    /**
825
     * @param int $forumId
826
     *
827
     * @throws Exception
828
     *
829
     * @return array
830
     */
831
    public function getCourseForum($forumId)
832
    {
833
        Event::event_access_tool(TOOL_FORUM);
834
835
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
836
837
        $sessionId = $this->session ? $this->session->getId() : 0;
838
        $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
839
840
        if (!isset($forumInfo['iid'])) {
841
            throw new Exception(get_lang('NoForum'));
842
        }
843
844
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
845
        $forum = [
846
            'id' => $forumInfo['iid'],
847
            'title' => $forumInfo['forum_title'],
848
            'description' => $forumInfo['forum_comment'],
849
            'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
850
            'threads' => [],
851
        ];
852
853
        $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
854
855
        foreach ($threads as $thread) {
856
            $forum['threads'][] = [
857
                'id' => $thread['iid'],
858
                'title' => $thread['thread_title'],
859
                'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
860
                'numberOfReplies' => $thread['thread_replies'],
861
                'numberOfViews' => $thread['thread_views'],
862
                'author' => api_get_person_name($thread['firstname'], $thread['lastname']),
863
            ];
864
        }
865
866
        return $forum;
867
    }
868
869
    /**
870
     * @param int $forumId
871
     * @param int $threadId
872
     *
873
     * @return array
874
     */
875
    public function getCourseForumThread($forumId, $threadId)
876
    {
877
        Event::event_access_tool(TOOL_FORUM);
878
879
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
880
881
        $sessionId = $this->session ? $this->session->getId() : 0;
882
        $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
883
884
        $thread = [
885
            'id' => intval($threadInfo['iid']),
886
            'cId' => intval($threadInfo['c_id']),
887
            'title' => $threadInfo['thread_title'],
888
            'forumId' => intval($threadInfo['forum_id']),
889
            'posts' => [],
890
        ];
891
892
        $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
893
        $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
894
895
        foreach ($postsInfo as $postInfo) {
896
            $thread['posts'][] = [
897
                'id' => $postInfo['iid'],
898
                'title' => $postInfo['post_title'],
899
                'text' => $postInfo['post_text'],
900
                'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
901
                'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
902
                'parentId' => $postInfo['post_parent_id'],
903
                'attachments' => getAttachedFiles(
904
                    $forumId,
905
                    $threadId,
906
                    $postInfo['iid'],
907
                    0,
908
                    $this->course->getId()
909
                ),
910
            ];
911
        }
912
913
        return $thread;
914
    }
915
916
    public function getCourseLinks(): array
917
    {
918
        Event::event_access_tool(TOOL_LINK);
919
920
        $courseId = $this->course->getId();
921
        $sessionId = $this->session ? $this->session->getId() : 0;
922
923
        $webCodePath = api_get_path(WEB_CODE_PATH);
924
        $cidReq = api_get_cidreq();
925
926
        $categories = array_merge(
927
            [
928
                [
929
                    'iid' => 0,
930
                    'c_id' => $courseId,
931
                    'id' => 0,
932
                    'category_title' => get_lang('NoCategory'),
933
                    'description' => '',
934
                    'display_order' => 0,
935
                    'session_id' => $sessionId,
936
                    'visibility' => 1,
937
                ],
938
            ],
939
            Link::getLinkCategories($courseId, $sessionId)
940
        );
941
942
        $categories = array_filter(
943
            $categories,
944
            function (array $category) {
945
                return $category['visibility'] != 0;
946
            }
947
        );
948
949
        return array_map(
950
            function (array $category) use ($webCodePath, $cidReq, $courseId, $sessionId) {
951
                $links = array_filter(
952
                    Link::getLinksPerCategory($category['iid'], $courseId, $sessionId),
953
                    function (array $link) {
954
                        return $link['visibility'] != 0;
955
                    }
956
                );
957
958
                $links = array_map(
959
                    function (array $link) use ($webCodePath, $cidReq) {
960
                        return [
961
                            'id' => (int) $link['id'],
962
                            'title' => Security::remove_XSS($link['title']),
963
                            'description' => Security::remove_XSS($link['description']),
964
                            'visibility' => (int) $link['visibility'],
965
                            'url' => $webCodePath."link/link_goto.php?$cidReq&link_id=".$link['id'],
966
                        ];
967
                    },
968
                    $links
969
                );
970
971
                return [
972
                    'id' => (int) $category['iid'],
973
                    'title' => Security::remove_XSS($category['category_title']),
974
                    'description' => Security::remove_XSS($category['description']),
975
                    'visibility' => (int) $category['visibility'],
976
                    'links' => $links,
977
                ];
978
            },
979
            $categories
980
        );
981
    }
982
983
    /**
984
     * @return array
985
     */
986
    public function getUserProfile()
987
    {
988
        $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
989
990
        $result = [
991
            'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
992
            'id' => $this->user->getId(),
993
            'status' => $this->user->getStatus(),
994
            'fullName' => UserManager::formatUserFullName($this->user),
995
            'username' => $this->user->getUsername(),
996
            'officialCode' => $this->user->getOfficialCode(),
997
            'phone' => $this->user->getPhone(),
998
            'extra' => [],
999
        ];
1000
1001
        $fieldValue = new ExtraFieldValue('user');
1002
        $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
1003
1004
        foreach ($extraInfo as $extra) {
1005
            /** @var ExtraFieldValues $extraValue */
1006
            $extraValue = $extra['value'];
1007
            $result['extra'][] = [
1008
                'title' => $extraValue->getField()->getDisplayText(true),
1009
                'value' => $extraValue->getValue(),
1010
            ];
1011
        }
1012
1013
        return $result;
1014
    }
1015
1016
    public function getCourseLpProgress()
1017
    {
1018
        $sessionId = $this->session ? $this->session->getId() : 0;
1019
        $userId = $this->user->getId();
1020
1021
        /*$sessionId = $this->session ? $this->session->getId() : 0;
1022
        $courseId = $this->course->getId();*/
1023
1024
        $result = Tracking::getCourseLpProgress($userId, $sessionId);
1025
1026
        return [$result];
1027
    }
1028
1029
    /**
1030
     * @throws Exception
1031
     *
1032
     * @return array
1033
     */
1034
    public function getCourseLearnPaths()
1035
    {
1036
        Event::event_access_tool(TOOL_LEARNPATH);
1037
1038
        $sessionId = $this->session ? $this->session->getId() : 0;
1039
        $categoriesTempList = learnpath::getCategories($this->course->getId());
1040
1041
        $categoryNone = new CLpCategory();
1042
        $categoryNone->setId(0);
1043
        $categoryNone->setName(get_lang('WithOutCategory'));
1044
        $categoryNone->setPosition(0);
1045
1046
        $categories = array_merge([$categoryNone], $categoriesTempList);
1047
        $categoryData = [];
1048
1049
        /** @var CLpCategory $category */
1050
        foreach ($categories as $category) {
1051
            $learnPathList = new LearnpathList(
1052
                $this->user->getId(),
1053
                api_get_course_info($this->course->getCode()),
1054
                $sessionId,
1055
                null,
1056
                false,
1057
                $category->getId()
1058
            );
1059
1060
            $flatLpList = $learnPathList->get_flat_list();
1061
1062
            if (empty($flatLpList)) {
1063
                continue;
1064
            }
1065
1066
            $listData = [];
1067
1068
            foreach ($flatLpList as $lpId => $lpDetails) {
1069
                if ($lpDetails['lp_visibility'] == 0) {
1070
                    continue;
1071
                }
1072
1073
                if (!learnpath::is_lp_visible_for_student(
1074
                    $lpId,
1075
                    $this->user->getId(),
1076
                    api_get_course_info($this->course->getCode()),
1077
                    $sessionId
1078
                )) {
1079
                    continue;
1080
                }
1081
1082
                $timeLimits = false;
1083
1084
                // This is an old LP (from a migration 1.8.7) so we do nothing
1085
                if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
1086
                    $timeLimits = false;
1087
                }
1088
1089
                // Checking if expired_on is ON
1090
                if (!empty($lpDetails['expired_on'])) {
1091
                    $timeLimits = true;
1092
                }
1093
1094
                if ($timeLimits) {
1095
                    if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
1096
                        $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
1097
                        $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
1098
                        $now = time();
1099
                        $isActiveTime = false;
1100
1101
                        if ($now > $startTime && $endTime > $now) {
1102
                            $isActiveTime = true;
1103
                        }
1104
1105
                        if (!$isActiveTime) {
1106
                            continue;
1107
                        }
1108
                    }
1109
                }
1110
1111
                $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
1112
1113
                $listData[] = [
1114
                    'id' => $lpId,
1115
                    'title' => Security::remove_XSS($lpDetails['lp_name']),
1116
                    'progress' => $progress,
1117
                    'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query(
1118
                        [
1119
                            'hash' => $this->encodeParams(
1120
                                [
1121
                                    'action' => 'course_learnpath',
1122
                                    'lp_id' => $lpId,
1123
                                    'course' => $this->course->getId(),
1124
                                    'session' => $sessionId,
1125
                                ]
1126
                            ),
1127
                        ]
1128
                    ),
1129
                ];
1130
            }
1131
1132
            if (empty($listData)) {
1133
                continue;
1134
            }
1135
1136
            $categoryData[] = [
1137
                'id' => $category->getId(),
1138
                'name' => $category->getName(),
1139
                'learnpaths' => $listData,
1140
            ];
1141
        }
1142
1143
        return $categoryData;
1144
    }
1145
1146
    /**
1147
     * Start login for a user. Then make a redirect to show the learnpath.
1148
     *
1149
     * @param int $lpId
1150
     */
1151
    public function showLearningPath($lpId)
1152
    {
1153
        $loggedUser['user_id'] = $this->user->getId();
1154
        $loggedUser['status'] = $this->user->getStatus();
1155
        $loggedUser['uidReset'] = true;
1156
        $sessionId = $this->session ? $this->session->getId() : 0;
1157
1158
        ChamiloSession::write('_user', $loggedUser);
1159
        Login::init_user($this->user->getId(), true);
1160
1161
        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query(
1162
            [
1163
                'cidReq' => $this->course->getCode(),
1164
                'id_session' => $sessionId,
1165
                'gidReq' => 0,
1166
                'gradebook' => 0,
1167
                'origin' => '',
1168
                'action' => 'view',
1169
                'lp_id' => (int) $lpId,
1170
                'isStudentView' => 'true',
1171
            ]
1172
        );
1173
1174
        header("Location: $url");
1175
        exit;
1176
    }
1177
1178
    /**
1179
     * @param int $forumId
1180
     *
1181
     * @return array
1182
     */
1183
    public function saveForumPost(array $postValues, $forumId)
1184
    {
1185
        Event::event_access_tool(TOOL_FORUM);
1186
1187
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1188
1189
        $forum = get_forums($forumId, $this->course->getCode());
1190
        store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
1191
1192
        return [
1193
            'registered' => true,
1194
        ];
1195
    }
1196
1197
    /**
1198
     * Get the list of sessions for current user.
1199
     *
1200
     * @return array the sessions list
1201
     */
1202
    public function getUserSessions()
1203
    {
1204
        $data = [];
1205
        $sessionsByCategory = UserManager::get_sessions_by_category($this->user->getId(), false);
1206
1207
        $webCodePath = api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?';
1208
1209
        foreach ($sessionsByCategory as $category) {
1210
            $categorySessions = [];
1211
1212
            foreach ($category['sessions'] as $sessions) {
1213
                $sessionCourses = [];
1214
1215
                foreach ($sessions['courses'] as $course) {
1216
                    $courseInfo = api_get_course_info_by_id($course['real_id']);
1217
                    $teachers = SessionManager::getCoachesByCourseSessionToString(
1218
                        $sessions['session_id'],
1219
                        $course['real_id']
1220
                    );
1221
1222
                    $sessionCourses[] = [
1223
                        'id' => $courseInfo['real_id'],
1224
                        'title' => $courseInfo['title'],
1225
                        'code' => $courseInfo['code'],
1226
                        'directory' => $courseInfo['directory'],
1227
                        'pictureUrl' => $courseInfo['course_image_large'],
1228
                        'urlPicture' => $courseInfo['course_image_large'],
1229
                        'teachers' => $teachers,
1230
                        'url' => $webCodePath.http_build_query(
1231
                            [
1232
                                'action' => self::VIEW_COURSE_HOME,
1233
                                'api_key' => $this->apiKey,
1234
                                'username' => $this->user->getUsername(),
1235
                                'course' => $courseInfo['real_id'],
1236
                                'session' => $sessions['session_id'],
1237
                            ]
1238
                        ),
1239
                    ];
1240
                }
1241
1242
                $sessionBox = Display::getSessionTitleBox($sessions['session_id']);
1243
1244
                $categorySessions[] = [
1245
                    'name' => $sessionBox['title'],
1246
                    'id' => $sessions['session_id'],
1247
                    'date' => $sessionBox['dates'],
1248
                    'duration' => isset($sessionBox['duration']) ? $sessionBox['duration'] : null,
1249
                    'courses' => $sessionCourses,
1250
                ];
1251
            }
1252
1253
            $data[] = [
1254
                'id' => $category['session_category']['id'],
1255
                'name' => $category['session_category']['name'],
1256
                'sessions' => $categorySessions,
1257
            ];
1258
        }
1259
1260
        return $data;
1261
    }
1262
1263
    public function getUsersSubscribedToCourse()
1264
    {
1265
        $users = CourseManager::get_user_list_from_course_code($this->course->getCode());
1266
1267
        $userList = [];
1268
        foreach ($users as $user) {
1269
            $userList[] = [
1270
                'user_id' => $user['user_id'],
1271
                'username' => $user['username'],
1272
                'firstname' => $user['firstname'],
1273
                'lastname' => $user['lastname'],
1274
                'status_rel' => $user['status_rel'],
1275
            ];
1276
        }
1277
1278
        return $userList;
1279
    }
1280
1281
    /**
1282
     * @param string $subject
1283
     * @param string $text
1284
     *
1285
     * @return array
1286
     */
1287
    public function saveUserMessage($subject, $text, array $receivers)
1288
    {
1289
        foreach ($receivers as $userId) {
1290
            MessageManager::send_message($userId, $subject, $text);
1291
        }
1292
1293
        return [
1294
            'sent' => true,
1295
        ];
1296
    }
1297
1298
    /**
1299
     * @param string $search
1300
     *
1301
     * @return array
1302
     */
1303
    public function getMessageUsers($search)
1304
    {
1305
        $repo = UserManager::getRepository();
1306
1307
        $users = $repo->findUsersToSendMessage($this->user->getId(), $search);
1308
        $showEmail = api_get_setting('show_email_addresses') === 'true';
1309
        $data = [];
1310
1311
        /** @var User $user */
1312
        foreach ($users as $user) {
1313
            $userName = UserManager::formatUserFullName($user);
1314
1315
            if ($showEmail) {
1316
                $userName .= " ({$user->getEmail()})";
1317
            }
1318
1319
            $data[] = [
1320
                'id' => $user->getId(),
1321
                'name' => $userName,
1322
            ];
1323
        }
1324
1325
        return $data;
1326
    }
1327
1328
    /**
1329
     * @param string $title
1330
     * @param string $text
1331
     *
1332
     * @return array
1333
     */
1334
    public function saveCourseNotebook($title, $text)
1335
    {
1336
        Event::event_access_tool(TOOL_NOTEBOOK);
1337
1338
        $values = ['note_title' => $title, 'note_comment' => $text];
1339
        $sessionId = $this->session ? $this->session->getId() : 0;
1340
1341
        $noteBookId = NotebookManager::save_note(
1342
            $values,
1343
            $this->user->getId(),
1344
            $this->course->getId(),
1345
            $sessionId
1346
        );
1347
1348
        return [
1349
            'registered' => $noteBookId,
1350
        ];
1351
    }
1352
1353
    /**
1354
     * @param int $forumId
1355
     *
1356
     * @return array
1357
     */
1358
    public function saveForumThread(array $values, $forumId)
1359
    {
1360
        Event::event_access_tool(TOOL_FORUM);
1361
1362
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1363
1364
        $sessionId = $this->session ? $this->session->getId() : 0;
1365
        $forum = get_forums($forumId, $this->course->getCode(), true, $sessionId);
1366
        $courseInfo = api_get_course_info($this->course->getCode());
1367
        $thread = store_thread($forum, $values, $courseInfo, false, $this->user->getId(), $sessionId);
1368
1369
        return [
1370
            'registered' => $thread->getIid(),
1371
        ];
1372
    }
1373
1374
    /**
1375
     * @return array
1376
     */
1377
    public function getUsersCampus(array $params)
1378
    {
1379
        $conditions = [
1380
            'status' => $params['status'],
1381
        ];
1382
        $idCampus = $params['id_campus'];
1383
        $users = UserManager::get_user_list($conditions, ['firstname'], false, false, $idCampus);
1384
        $list = [];
1385
        foreach ($users as $item) {
1386
            $listTemp = [
1387
                'id' => $item['user_id'],
1388
                'firstname' => $item['firstname'],
1389
                'lastname' => $item['lastname'],
1390
                'email' => $item['email'],
1391
            ];
1392
            $list[] = $listTemp;
1393
        }
1394
1395
        return $list;
1396
    }
1397
1398
    /**
1399
     * @return array
1400
     */
1401
    public function getCoursesCampus(array $params)
1402
    {
1403
        $idCampus = $params['id_campus'];
1404
1405
        return CourseManager::get_courses_list(
1406
            0, //offset
1407
            0, //howMany
1408
            1, //$orderby = 1
1409
            'ASC',
1410
            -1, //visibility
1411
            null,
1412
            $idCampus, //$urlId
1413
            true //AlsoSearchCode
1414
        );
1415
    }
1416
1417
    /**
1418
     * @return array
1419
     */
1420
    public function addSession(array $params)
1421
    {
1422
        $name = $params['name'];
1423
        $coach_username = (int) $params['coach_username'];
1424
        $startDate = $params['access_start_date'];
1425
        $endDate = $params['access_end_date'];
1426
        $displayStartDate = $startDate;
1427
        $displayEndDate = $endDate;
1428
        $description = $params['description'];
1429
        $idUrlCampus = $params['id_campus'];
1430
        $extraFields = isset($params['extra']) ? $params['extra'] : [];
1431
1432
        $return = SessionManager::create_session(
1433
            $name,
1434
            $startDate,
1435
            $endDate,
1436
            $displayStartDate,
1437
            $displayEndDate,
1438
            null,
1439
            null,
1440
            $coach_username,
1441
            null,
1442
            1,
1443
            false,
1444
            null,
1445
            $description,
1446
            1,
1447
            $extraFields,
1448
            null,
1449
            false,
1450
            $idUrlCampus
1451
        );
1452
1453
        if ($return) {
1454
            $out = [
1455
                'status' => true,
1456
                'message' => get_lang('ANewSessionWasCreated'),
1457
                'id_session' => $return,
1458
            ];
1459
        } else {
1460
            $out = [
1461
                'status' => false,
1462
                'message' => get_lang('ErrorOccurred'),
1463
            ];
1464
        }
1465
1466
        return $out;
1467
    }
1468
1469
    public function addCourse(array $courseParam): array
1470
    {
1471
        $idCampus = isset($courseParam['id_campus']) ? $courseParam['id_campus'] : 1;
1472
        $title = isset($courseParam['title']) ? $courseParam['title'] : '';
1473
        $wantedCode = isset($courseParam['wanted_code']) ? $courseParam['wanted_code'] : null;
1474
        $diskQuota = isset($courseParam['disk_quota']) ? $courseParam['disk_quota'] : '100';
1475
        $visibility = isset($courseParam['visibility']) ? (int) $courseParam['visibility'] : null;
1476
        $removeCampusId = $courseParam['remove_campus_id_from_wanted_code'] ?? 0;
1477
        $language = $courseParam['language'] ?? '';
1478
1479
        if (isset($courseParam['visibility'])) {
1480
            if ($courseParam['visibility'] &&
1481
                $courseParam['visibility'] >= 0 &&
1482
                $courseParam['visibility'] <= 3
1483
            ) {
1484
                $visibility = (int) $courseParam['visibility'];
1485
            }
1486
        }
1487
1488
        $params = [];
1489
        $params['title'] = $title;
1490
        $params['wanted_code'] = 'CAMPUS_'.$idCampus.'_'.$wantedCode;
1491
        if (1 === (int) $removeCampusId) {
1492
            $params['wanted_code'] = $wantedCode;
1493
        }
1494
        $params['user_id'] = $this->user->getId();
1495
        $params['visibility'] = $visibility;
1496
        $params['disk_quota'] = $diskQuota;
1497
        $params['course_language'] = $language;
1498
1499
        foreach ($courseParam as $key => $value) {
1500
            if (substr($key, 0, 6) === 'extra_') { //an extra field
1501
                $params[$key] = $value;
1502
            }
1503
        }
1504
1505
        $courseInfo = CourseManager::create_course($params, $params['user_id'], $idCampus);
1506
        $results = [];
1507
        if (!empty($courseInfo)) {
1508
            $results['status'] = true;
1509
            $results['code_course'] = $courseInfo['code'];
1510
            $results['title_course'] = $courseInfo['title'];
1511
            $extraFieldValues = new ExtraFieldValue('course');
1512
            $extraFields = $extraFieldValues->getAllValuesByItem($courseInfo['real_id']);
1513
            $results['extra_fields'] = $extraFields;
1514
            $results['message'] = sprintf(get_lang('CourseXAdded'), $courseInfo['code']);
1515
        } else {
1516
            $results['status'] = false;
1517
            $results['message'] = get_lang('CourseCreationFailed');
1518
        }
1519
1520
        return $results;
1521
    }
1522
1523
    /**
1524
     * @param $userParam
1525
     *
1526
     * @throws Exception
1527
     *
1528
     * @return array
1529
     */
1530
    public function addUser($userParam)
1531
    {
1532
        $firstName = $userParam['firstname'];
1533
        $lastName = $userParam['lastname'];
1534
        $status = $userParam['status'];
1535
        $email = $userParam['email'];
1536
        $loginName = $userParam['loginname'];
1537
        $password = $userParam['password'];
1538
1539
        $official_code = '';
1540
        $language = '';
1541
        $phone = '';
1542
        $picture_uri = '';
1543
        $auth_source = $userParam['auth_source'] ?? PLATFORM_AUTH_SOURCE;
1544
        $expiration_date = '';
1545
        $active = 1;
1546
        $hr_dept_id = 0;
1547
        $original_user_id_name = $userParam['original_user_id_name'];
1548
        $original_user_id_value = $userParam['original_user_id_value'];
1549
1550
        $extra_list = isset($userParam['extra']) ? $userParam['extra'] : [];
1551
        if (isset($userParam['language'])) {
1552
            $language = $userParam['language'];
1553
        }
1554
        if (isset($userParam['phone'])) {
1555
            $phone = $userParam['phone'];
1556
        }
1557
        if (isset($userParam['expiration_date'])) {
1558
            $expiration_date = $userParam['expiration_date'];
1559
        }
1560
1561
        // Default language.
1562
        if (empty($language)) {
1563
            $language = api_get_setting('platformLanguage');
1564
        }
1565
1566
        // First check wether the login already exists.
1567
        if (!UserManager::is_username_available($loginName)) {
1568
            throw new Exception(get_lang('UserNameNotAvailable'));
1569
        }
1570
1571
        $userId = UserManager::create_user(
1572
            $firstName,
1573
            $lastName,
1574
            $status,
1575
            $email,
1576
            $loginName,
1577
            $password,
1578
            $official_code,
1579
            $language,
1580
            $phone,
1581
            $picture_uri,
1582
            $auth_source,
1583
            $expiration_date,
1584
            $active,
1585
            $hr_dept_id
1586
        );
1587
1588
        if (empty($userId)) {
1589
            throw new Exception(get_lang('UserNotRegistered'));
1590
        }
1591
1592
        if (api_is_multiple_url_enabled()) {
1593
            if (api_get_current_access_url_id() != -1) {
1594
                UrlManager::add_user_to_url(
1595
                    $userId,
1596
                    api_get_current_access_url_id()
1597
                );
1598
            } else {
1599
                UrlManager::add_user_to_url($userId, 1);
1600
            }
1601
        } else {
1602
            // We add by default the access_url_user table with access_url_id = 1
1603
            UrlManager::add_user_to_url($userId, 1);
1604
        }
1605
1606
        // Save new field label into user_field table.
1607
        UserManager::create_extra_field(
1608
            $original_user_id_name,
1609
            1,
1610
            $original_user_id_name,
1611
            ''
1612
        );
1613
        // Save the external system's id into user_field_value table.
1614
        UserManager::update_extra_field_value(
1615
            $userId,
1616
            $original_user_id_name,
1617
            $original_user_id_value
1618
        );
1619
1620
        if (is_array($extra_list) && count($extra_list) > 0) {
1621
            foreach ($extra_list as $extra) {
1622
                $extra_field_name = $extra['field_name'];
1623
                $extra_field_value = $extra['field_value'];
1624
                // Save new field label into user_field table.
1625
                UserManager::create_extra_field(
1626
                    $extra_field_name,
1627
                    1,
1628
                    $extra_field_name,
1629
                    ''
1630
                );
1631
                // Save the external system's id into user_field_value table.
1632
                UserManager::update_extra_field_value(
1633
                    $userId,
1634
                    $extra_field_name,
1635
                    $extra_field_value
1636
                );
1637
            }
1638
        }
1639
1640
        return [$userId];
1641
    }
1642
1643
    /**
1644
     * @throws Exception
1645
     */
1646
    public function addUserGetApikey(array $userParams): array
1647
    {
1648
        list($userId) = $this->addUser($userParams);
1649
1650
        UserManager::add_api_key($userId, self::SERVICE_NAME);
1651
1652
        $apiKey = UserManager::get_api_keys($userId, self::SERVICE_NAME);
1653
1654
        return [
1655
            'id' => $userId,
1656
            'api_key' => current($apiKey),
1657
        ];
1658
    }
1659
1660
    /**
1661
     * @throws Exception
1662
     */
1663
    public function updateUserApiKey(int $userId, string $oldApiKey): array
1664
    {
1665
        if (false === $currentApiKeys = UserManager::get_api_keys($userId, self::SERVICE_NAME)) {
1666
            throw new Exception(get_lang('NotAllowed'));
1667
        }
1668
1669
        if (current($currentApiKeys) !== $oldApiKey) {
1670
            throw new Exception(get_lang('NotAllowed'));
1671
        }
1672
1673
        UserManager::update_api_key($userId, self::SERVICE_NAME);
1674
1675
        $apiKey = UserManager::get_api_keys($userId, self::SERVICE_NAME);
1676
1677
        return [
1678
            'api_key' => current($apiKey),
1679
        ];
1680
    }
1681
1682
    /**
1683
     * Subscribe User to Course.
1684
     *
1685
     * @param array $params
1686
     *
1687
     * @return array
1688
     */
1689
    public function subscribeUserToCourse($params)
1690
    {
1691
        $course_id = $params['course_id'];
1692
        $course_code = $params['course_code'];
1693
        $user_id = $params['user_id'];
1694
        $status = $params['status'] ?? STUDENT;
1695
1696
        if (!$course_id && !$course_code) {
1697
            return [false];
1698
        }
1699
        if (!$course_code) {
1700
            $course_code = CourseManager::get_course_code_from_course_id($course_id);
1701
        }
1702
1703
        if (CourseManager::subscribeUser($user_id, $course_code, $status, 0, 0, false)) {
1704
            return [true];
1705
        }
1706
1707
        return [false];
1708
    }
1709
1710
    /**
1711
     * @throws Exception
1712
     */
1713
    public function subscribeUserToCoursePassword($courseCode, $password)
1714
    {
1715
        $courseInfo = api_get_course_info($courseCode);
1716
1717
        if (empty($courseInfo)) {
1718
            throw new Exception(get_lang('NoCourse'));
1719
        }
1720
1721
        if (sha1($password) === $courseInfo['registration_code']) {
1722
            CourseManager::processAutoSubscribeToCourse($courseCode);
1723
1724
            return;
1725
        }
1726
1727
        throw new Exception(get_lang('CourseRegistrationCodeIncorrect'));
1728
    }
1729
1730
    public function unSubscribeUserToCourse(array $params): array
1731
    {
1732
        $courseId = $params['course_id'];
1733
        $courseCode = $params['course_code'];
1734
        $userId = $params['user_id'];
1735
1736
        if (!$courseId && !$courseCode) {
1737
            return [false];
1738
        }
1739
1740
        if (!$courseCode) {
1741
            $courseCode = CourseManager::get_course_code_from_course_id($courseId);
1742
        }
1743
1744
        if (CourseManager::unsubscribe_user($userId, $courseCode)) {
1745
            return [true];
1746
        }
1747
1748
        return [false];
1749
    }
1750
1751
    public function deleteUserMessage($messageId, $messageType)
1752
    {
1753
        if ($messageType === 'sent') {
1754
            return MessageManager::delete_message_by_user_sender($this->user->getId(), $messageId);
1755
        } else {
1756
            return MessageManager::delete_message_by_user_receiver($this->user->getId(), $messageId);
1757
        }
1758
    }
1759
1760
    public function setMessageRead($messageId)
1761
    {
1762
        MessageManager::update_message($this->user->getId(), $messageId);
1763
    }
1764
1765
    /**
1766
     * Add Campus Virtual.
1767
     *
1768
     * @param array Params Campus
1769
     *
1770
     * @return array
1771
     */
1772
    public function createCampusURL($params)
1773
    {
1774
        $urlCampus = Security::remove_XSS($params['url']);
1775
        $description = Security::remove_XSS($params['description']);
1776
1777
        $active = isset($params['active']) ? intval($params['active']) : 0;
1778
        $num = UrlManager::url_exist($urlCampus);
1779
        if ($num == 0) {
1780
            // checking url
1781
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1782
                $idCampus = UrlManager::add($urlCampus, $description, $active, true);
1783
            } else {
1784
                //create
1785
                $idCampus = UrlManager::add($urlCampus.'/', $description, $active, true);
1786
            }
1787
1788
            return [
1789
                'status' => true,
1790
                'id_campus' => $idCampus,
1791
            ];
1792
        }
1793
1794
        return [
1795
            'status' => false,
1796
            'id_campus' => 0,
1797
        ];
1798
    }
1799
1800
    /**
1801
     * Edit Campus Virtual.
1802
     *
1803
     * @param array Params Campus
1804
     *
1805
     * @return array
1806
     */
1807
    public function editCampusURL($params)
1808
    {
1809
        $urlCampus = Security::remove_XSS($params['url']);
1810
        $description = Security::remove_XSS($params['description']);
1811
1812
        $active = isset($params['active']) ? intval($params['active']) : 0;
1813
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1814
1815
        if (!empty($url_id)) {
1816
            //we can't change the status of the url with id=1
1817
            if ($url_id == 1) {
1818
                $active = 1;
1819
            }
1820
            //checking url
1821
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1822
                UrlManager::update($url_id, $urlCampus, $description, $active);
1823
            } else {
1824
                UrlManager::update($url_id, $urlCampus.'/', $description, $active);
1825
            }
1826
1827
            return [true];
1828
        }
1829
1830
        return [false];
1831
    }
1832
1833
    /**
1834
     * Delete Campus Virtual.
1835
     *
1836
     * @param array Params Campus
1837
     *
1838
     * @return array
1839
     */
1840
    public function deleteCampusURL($params)
1841
    {
1842
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1843
1844
        $result = UrlManager::delete($url_id);
1845
        if ($result) {
1846
            return [
1847
                'status' => true,
1848
                'message' => get_lang('URLDeleted'),
1849
            ];
1850
        } else {
1851
            return [
1852
                'status' => false,
1853
                'message' => get_lang('Error'),
1854
            ];
1855
        }
1856
    }
1857
1858
    /**
1859
     * @throws Exception
1860
     *
1861
     * @return array
1862
     */
1863
    public function addCoursesSession(array $params)
1864
    {
1865
        $sessionId = $params['id_session'];
1866
        $courseList = $params['list_courses'];
1867
        $importAssignments = isset($params['import_assignments']) ? 1 === (int) $params['import_assignments'] : false;
1868
1869
        $result = SessionManager::add_courses_to_session(
1870
            $sessionId,
1871
            $courseList,
1872
            true,
1873
            false,
1874
            false,
1875
            $importAssignments
1876
        );
1877
1878
        if ($result) {
1879
            return [
1880
                'status' => $result,
1881
                'message' => get_lang('Updated'),
1882
            ];
1883
        }
1884
1885
        return [
1886
            'status' => $result,
1887
            'message' => get_lang('ErrorOccurred'),
1888
        ];
1889
    }
1890
1891
    /**
1892
     * @return array
1893
     */
1894
    public function addUsersSession(array $params)
1895
    {
1896
        $sessionId = $params['id_session'];
1897
        $userList = $params['list_users'];
1898
1899
        if (!is_array($userList)) {
1900
            $userList = [];
1901
        }
1902
1903
        SessionManager::subscribeUsersToSession(
1904
            $sessionId,
1905
            $userList,
1906
            null,
1907
            false
1908
        );
1909
1910
        return [
1911
            'status' => true,
1912
            'message' => get_lang('UsersAdded'),
1913
        ];
1914
    }
1915
1916
    /**
1917
     * Creates a session from a model session.
1918
     *
1919
     * @throws Exception
1920
     */
1921
    public function createSessionFromModel(HttpRequest $request): int
1922
    {
1923
        $modelSessionId = $request->request->getInt('modelSessionId');
1924
        $sessionName = $request->request->get('sessionName');
1925
        $startDate = $request->request->get('startDate');
1926
        $endDate = $request->request->get('endDate');
1927
        $extraFields = $request->request->get('extraFields', []);
1928
        $duplicateAgendaContent = $request->request->getBoolean('duplicateAgendaContent');
1929
1930
        if (empty($modelSessionId) || empty($sessionName) || empty($startDate) || empty($endDate)) {
1931
            throw new Exception(get_lang('NoData'));
1932
        }
1933
1934
        if (!SessionManager::isValidId($modelSessionId)) {
1935
            throw new Exception(get_lang('ModelSessionDoesNotExist'));
1936
        }
1937
1938
        $modelSession = SessionManager::fetch($modelSessionId);
1939
1940
        $modelSession['accessUrlId'] = 1;
1941
        if (api_is_multiple_url_enabled()) {
1942
            if (api_get_current_access_url_id() != -1) {
1943
                $modelSession['accessUrlId'] = api_get_current_access_url_id();
1944
            }
1945
        }
1946
1947
        $newSessionId = SessionManager::create_session(
1948
            $sessionName,
1949
            $startDate,
1950
            $endDate,
1951
            $startDate,
1952
            $endDate,
1953
            $startDate,
1954
            $endDate,
1955
            $modelSession['id_coach'],
1956
            $modelSession['session_category_id'],
1957
            $modelSession['visibility'],
1958
            false,
1959
            $modelSession['duration'],
1960
            $modelSession['description'],
1961
            $modelSession['show_description'],
1962
            $extraFields,
1963
            $modelSession['session_admin_id'],
1964
            $modelSession['send_subscription_notification'],
1965
            $modelSession['accessUrlId']
1966
        );
1967
1968
        if (empty($newSessionId)) {
1969
            throw new Exception(get_lang('SessionNotRegistered'));
1970
        }
1971
1972
        if (is_string($newSessionId)) {
1973
            throw new Exception($newSessionId);
1974
        }
1975
1976
        $promotionId = $modelSession['promotion_id'];
1977
        if ($promotionId) {
1978
            $sessionList = array_keys(SessionManager::get_all_sessions_by_promotion($promotionId));
1979
            $sessionList[] = $newSessionId;
1980
            SessionManager::subscribe_sessions_to_promotion($modelSession['promotion_id'], $sessionList);
1981
        }
1982
1983
        $modelExtraFields = [];
1984
        $fields = SessionManager::getFilteredExtraFields($modelSessionId);
1985
        if (is_array($fields) and !empty($fields)) {
1986
            foreach ($fields as $field) {
1987
                $modelExtraFields[$field['variable']] = $field['value'];
1988
            }
1989
        }
1990
        $allExtraFields = array_merge($modelExtraFields, $extraFields);
1991
        foreach ($allExtraFields as $name => $value) {
1992
            // SessionManager::update_session_extra_field_value returns false when no row is changed,
1993
            // which can happen since extra field values are initialized by SessionManager::create_session
1994
            // therefore we do not throw an exception when false is returned
1995
            SessionManager::update_session_extra_field_value($newSessionId, $name, $value);
1996
        }
1997
1998
        $courseList = array_keys(SessionManager::get_course_list_by_session_id($modelSessionId));
1999
        if (is_array($courseList)
2000
            && !empty($courseList)
2001
            && !SessionManager::add_courses_to_session($newSessionId, $courseList)) {
2002
            throw new Exception(get_lang('CoursesNotAddedToSession'));
2003
        }
2004
2005
        if ($duplicateAgendaContent) {
2006
            foreach ($courseList as $courseId) {
2007
                SessionManager::importAgendaFromSessionModel($modelSessionId, $newSessionId, $courseId);
2008
            }
2009
        }
2010
2011
        if (api_is_multiple_url_enabled()) {
2012
            if (api_get_current_access_url_id() != -1) {
2013
                UrlManager::add_session_to_url(
2014
                    $newSessionId,
2015
                    api_get_current_access_url_id()
2016
                );
2017
            } else {
2018
                UrlManager::add_session_to_url($newSessionId, 1);
2019
            }
2020
        } else {
2021
            UrlManager::add_session_to_url($newSessionId, 1);
2022
        }
2023
2024
        return $newSessionId;
2025
    }
2026
2027
    /**
2028
     * subscribes a user to a session.
2029
     *
2030
     * @param int    $sessionId the session id
2031
     * @param string $loginName the user's login name
2032
     *
2033
     * @throws Exception
2034
     *
2035
     * @return boolean, whether it worked
2036
     */
2037
    public function subscribeUserToSessionFromUsername($sessionId, $loginName)
2038
    {
2039
        if (!SessionManager::isValidId($sessionId)) {
2040
            throw new Exception(get_lang('SessionNotFound'));
2041
        }
2042
2043
        $userId = UserManager::get_user_id_from_username($loginName);
2044
        if (false === $userId) {
2045
            throw new Exception(get_lang('UserNotFound'));
2046
        }
2047
2048
        $subscribed = SessionManager::subscribeUsersToSession(
2049
            $sessionId,
2050
            [$userId],
2051
            SESSION_VISIBLE_READ_ONLY,
2052
            false
2053
        );
2054
        if (!$subscribed) {
2055
            throw new Exception(get_lang('UserNotSubscribed'));
2056
        }
2057
2058
        return true;
2059
    }
2060
2061
    /**
2062
     * finds the session which has a specific value in a specific extra field.
2063
     *
2064
     * @param $fieldName
2065
     * @param $fieldValue
2066
     *
2067
     * @throws Exception when no session matched or more than one session matched
2068
     *
2069
     * @return int, the matching session id
2070
     */
2071
    public function getSessionFromExtraField($fieldName, $fieldValue)
2072
    {
2073
        // find sessions that that have value in field
2074
        $valueModel = new ExtraFieldValue('session');
2075
        $sessionIdList = $valueModel->get_item_id_from_field_variable_and_field_value(
2076
            $fieldName,
2077
            $fieldValue,
2078
            false,
2079
            false,
2080
            true
2081
        );
2082
2083
        // throw if none found
2084
        if (empty($sessionIdList)) {
2085
            throw new Exception(get_lang('NoSessionMatched'));
2086
        }
2087
2088
        // throw if more than one found
2089
        if (count($sessionIdList) > 1) {
2090
            throw new Exception(get_lang('MoreThanOneSessionMatched'));
2091
        }
2092
2093
        // return sessionId
2094
        return intval($sessionIdList[0]['item_id']);
2095
    }
2096
2097
    /**
2098
     * updates a user identified by its login name.
2099
     *
2100
     * @param array $parameters
2101
     *
2102
     * @throws Exception on failure
2103
     *
2104
     * @return boolean, true on success
2105
     */
2106
    public function updateUserFromUserName($parameters)
2107
    {
2108
        // find user
2109
        $userId = null;
2110
        if (!is_array($parameters) || empty($parameters)) {
2111
            throw new Exception('NoData');
2112
        }
2113
        foreach ($parameters as $name => $value) {
2114
            if (strtolower($name) === 'loginname') {
2115
                $userId = UserManager::get_user_id_from_username($value);
2116
                if (false === $userId) {
2117
                    throw new Exception(get_lang('UserNotFound'));
2118
                }
2119
                break;
2120
            }
2121
        }
2122
        if (is_null($userId)) {
2123
            throw new Exception(get_lang('NoData'));
2124
        }
2125
        /** @var User $user */
2126
        $user = UserManager::getRepository()->find($userId);
2127
        if (empty($user)) {
2128
            throw new Exception(get_lang('CouldNotLoadUser'));
2129
        }
2130
2131
        // tell the world we are about to update a user
2132
        $hook = HookUpdateUser::create();
2133
        if (!empty($hook)) {
2134
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_PRE);
2135
        }
2136
2137
        // apply submitted modifications
2138
        foreach ($parameters as $name => $value) {
2139
            switch (strtolower($name)) {
2140
                case 'email':
2141
                    $user->setEmail($value);
2142
                    break;
2143
                case 'enabled':
2144
                    $user->setEnabled($value);
2145
                    break;
2146
                case 'lastname':
2147
                    $user->setLastname($value);
2148
                    break;
2149
                case 'firstname':
2150
                    $user->setFirstname($value);
2151
                    break;
2152
                case 'phone':
2153
                    $user->setPhone($value);
2154
                    break;
2155
                case 'address':
2156
                    $user->setAddress($value);
2157
                    break;
2158
                case 'roles':
2159
                    $user->setRoles($value);
2160
                    break;
2161
                case 'profile_completed':
2162
                    $user->setProfileCompleted($value);
2163
                    break;
2164
                case 'auth_source':
2165
                    $user->setAuthSource($value);
2166
                    break;
2167
                case 'status':
2168
                    $user->setStatus($value);
2169
                    break;
2170
                case 'official_code':
2171
                    $user->setOfficialCode($value);
2172
                    break;
2173
                case 'picture_uri':
2174
                    $user->setPictureUri($value);
2175
                    break;
2176
                case 'creator_id':
2177
                    $user->setCreatorId($value);
2178
                    break;
2179
                case 'competences':
2180
                    $user->setCompetences($value);
2181
                    break;
2182
                case 'diplomas':
2183
                    $user->setDiplomas($value);
2184
                    break;
2185
                case 'openarea':
2186
                    $user->setOpenArea($value);
2187
                    break;
2188
                case 'teach':
2189
                    $user->setTeach($value);
2190
                    break;
2191
                case 'productions':
2192
                    $user->setProductions($value);
2193
                    break;
2194
                case 'language':
2195
                    $languages = api_get_languages();
2196
                    if (!in_array($value, $languages['folder'])) {
2197
                        throw new Exception(get_lang('LanguageUnavailable'));
2198
                    }
2199
                    $user->setLanguage($value);
2200
                    break;
2201
                case 'registration_date':
2202
                    $user->setRegistrationDate($value);
2203
                    break;
2204
                case 'expiration_date':
2205
                    $user->setExpirationDate(
2206
                        new DateTime(
2207
                            api_get_utc_datetime($value),
2208
                            new DateTimeZone('UTC')
2209
                        )
2210
                    );
2211
                    break;
2212
                case 'active':
2213
                    // see UserManager::update_user() usermanager.lib.php:1205
2214
                    if ($user->getActive() != $value) {
2215
                        $user->setActive($value);
2216
                        Event::addEvent($value ? LOG_USER_ENABLE : LOG_USER_DISABLE, LOG_USER_ID, $userId);
2217
                    }
2218
                    break;
2219
                case 'openid':
2220
                    $user->setOpenId($value);
2221
                    break;
2222
                case 'theme':
2223
                    $user->setTheme($value);
2224
                    break;
2225
                case 'hr_dept_id':
2226
                    $user->setHrDeptId($value);
2227
                    break;
2228
                case 'extra':
2229
                    if (is_array($value)) {
2230
                        if (count($value) > 0) {
2231
                            if (is_array($value[0])) {
2232
                                foreach ($value as $field) {
2233
                                    $fieldName = $field['field_name'];
2234
                                    $fieldValue = $field['field_value'];
2235
                                    if (!isset($fieldName) || !isset($fieldValue) ||
2236
                                        !UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
2237
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.print_r($field, true));
2238
                                    }
2239
                                }
2240
                            } else {
2241
                                foreach ($value as $fieldName => $fieldValue) {
2242
                                    if (!UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
2243
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.$fieldName);
2244
                                    }
2245
                                }
2246
                            }
2247
                        }
2248
                    }
2249
                    break;
2250
                case 'username':
2251
                case 'api_key':
2252
                case 'action':
2253
                case 'loginname':
2254
                    break;
2255
                case 'email_canonical':
2256
                case 'locked':
2257
                case 'expired':
2258
                case 'credentials_expired':
2259
                case 'credentials_expire_at':
2260
                case 'expires_at':
2261
                case 'salt':
2262
                case 'last_login':
2263
                case 'created_at':
2264
                case 'updated_at':
2265
                case 'confirmation_token':
2266
                case 'password_requested_at':
2267
                case 'password': // see UserManager::update_user usermanager.lib.php:1182
2268
                case 'username_canonical':
2269
                default:
2270
                    throw new Exception(get_lang('UnsupportedUpdate')." '$name'");
2271
            }
2272
        }
2273
2274
        // save modifications
2275
        UserManager::getManager()->updateUser($user, true);
2276
2277
        // tell the world we just updated this user
2278
        if (!empty($hook)) {
2279
            $hook->setEventData(['user' => $user]);
2280
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST);
2281
        }
2282
2283
        // invalidate cache for this user
2284
        $cacheAvailable = api_get_configuration_value('apc');
2285
        if ($cacheAvailable === true) {
2286
            $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$userId;
2287
            if (apcu_exists($apcVar)) {
2288
                apcu_delete($apcVar);
2289
            }
2290
        }
2291
2292
        return true;
2293
    }
2294
2295
    /**
2296
     * Returns whether a user login name exists.
2297
     *
2298
     * @param string $loginname the user login name
2299
     *
2300
     * @return bool whether the user login name exists
2301
     */
2302
    public function usernameExist($loginname)
2303
    {
2304
        return false !== api_get_user_info_from_username($loginname);
2305
    }
2306
2307
    /**
2308
     * This service roughly matches what the call to MDL's API core_course_get_contents function returns.
2309
     *
2310
     * @return array
2311
     */
2312
    public function getCourseQuizMdlCompat()
2313
    {
2314
        $userId = $this->user->getId();
2315
        $courseId = $this->course->getId();
2316
        $sessionId = $this->session ? $this->session->getId() : 0;
2317
2318
        $toolVisibility = CourseHome::getToolVisibility(TOOL_QUIZ, $courseId, $sessionId);
2319
2320
        $json = [
2321
            "id" => $this->course->getId(),
2322
            "name" => get_lang('Exercises'),
2323
            "visible" => (int) $toolVisibility,
2324
            "summary" => '',
2325
            "summaryformat" => 1,
2326
            "section" => 1,
2327
            "hiddenbynumsections" => 0,
2328
            "uservisible" => $toolVisibility,
2329
            "modules" => [],
2330
        ];
2331
2332
        $quizIcon = Display::return_icon('quiz.png', '', [], ICON_SIZE_SMALL, false, true);
2333
2334
        $json['modules'] = array_map(
2335
            function (array $exercise) use ($quizIcon) {
2336
                return [
2337
                    'id' => (int) $exercise['id'],
2338
                    'url' => $exercise['url'],
2339
                    'name' => $exercise['name'],
2340
                    'instance' => 1,
2341
                    'visible' => 1,
2342
                    'uservisible' => true,
2343
                    'visibleoncoursepage' => 0,
2344
                    'modicon' => $quizIcon,
2345
                    'modname' => 'quiz',
2346
                    'modplural' => get_lang('Exercises'),
2347
                    'availability' => null,
2348
                    'indent' => 0,
2349
                    'onclick' => '',
2350
                    'afterlink' => null,
2351
                    'customdata' => "",
2352
                    'noviewlink' => false,
2353
                    'completion' => (int) ($exercise[1] > 0),
2354
                ];
2355
            },
2356
            Exercise::exerciseGrid(0, '', $userId, $courseId, $sessionId, true)
2357
        );
2358
2359
        return [$json];
2360
    }
2361
2362
    /**
2363
     * @throws Exception
2364
     */
2365
    public function updateSession(array $params): array
2366
    {
2367
        $id = $params['session_id'];
2368
        $reset = $params['reset'] ?? null;
2369
        $name = $params['name'] ?? null;
2370
        $coachId = isset($params['id_coach']) ? (int) $params['id_coach'] : null;
2371
        $sessionCategoryId = isset($params['session_category_id']) ? (int) $params['session_category_id'] : null;
2372
        $description = $params['description'] ?? null;
2373
        $showDescription = $params['show_description'] ?? null;
2374
        $duration = $params['duration'] ?? null;
2375
        $visibility = $params['visibility'] ?? null;
2376
        $promotionId = $params['promotion_id'] ?? null;
2377
        $displayStartDate = $params['display_start_date'] ?? null;
2378
        $displayEndDate = $params['display_end_date'] ?? null;
2379
        $accessStartDate = $params['access_start_date'] ?? null;
2380
        $accessEndDate = $params['access_end_date'] ?? null;
2381
        $coachStartDate = $params['coach_access_start_date'] ?? null;
2382
        $coachEndDate = $params['coach_access_end_date'] ?? null;
2383
        $sendSubscriptionNotification = $params['send_subscription_notification'] ?? null;
2384
        $extraFields = $params['extra'] ?? [];
2385
2386
        $reset = (bool) $reset;
2387
        $visibility = (int) $visibility;
2388
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
2389
2390
        if (!SessionManager::isValidId($id)) {
2391
            throw new Exception(get_lang('NoData'));
2392
        }
2393
2394
        if (!empty($accessStartDate) && !api_is_valid_date($accessStartDate, 'Y-m-d H:i') &&
2395
            !api_is_valid_date($accessStartDate, 'Y-m-d H:i:s')
2396
        ) {
2397
            throw new Exception(get_lang('InvalidDate'));
2398
        }
2399
2400
        if (!empty($accessEndDate) && !api_is_valid_date($accessEndDate, 'Y-m-d H:i') &&
2401
            !api_is_valid_date($accessEndDate, 'Y-m-d H:i:s')
2402
        ) {
2403
            throw new Exception(get_lang('InvalidDate'));
2404
        }
2405
2406
        if (!empty($accessStartDate) && !empty($accessEndDate) && $accessStartDate >= $accessEndDate) {
2407
            throw new Exception(get_lang('InvalidDate'));
2408
        }
2409
2410
        $values = [];
2411
2412
        if ($reset) {
2413
            $values['name'] = $name;
2414
            $values['id_coach'] = $coachId;
2415
            $values['session_category_id'] = $sessionCategoryId;
2416
            $values['description'] = $description;
2417
            $values['show_description'] = $showDescription;
2418
            $values['duration'] = $duration;
2419
            $values['visibility'] = $visibility;
2420
            $values['promotion_id'] = $promotionId;
2421
            $values['display_start_date'] = !empty($displayStartDate) ? api_get_utc_datetime($displayStartDate) : null;
2422
            $values['display_end_date'] = !empty($displayEndDate) ? api_get_utc_datetime($displayEndDate) : null;
2423
            $values['access_start_date'] = !empty($accessStartDate) ? api_get_utc_datetime($accessStartDate) : null;
2424
            $values['access_end_date'] = !empty($accessEndDate) ? api_get_utc_datetime($accessEndDate) : null;
2425
            $values['coach_access_start_date'] = !empty($coachStartDate) ? api_get_utc_datetime($coachStartDate) : null;
2426
            $values['coach_access_end_date'] = !empty($coachEndDate) ? api_get_utc_datetime($coachEndDate) : null;
2427
            $values['send_subscription_notification'] = $sendSubscriptionNotification;
2428
        } else {
2429
            if (!empty($name)) {
2430
                $values['name'] = $name;
2431
            }
2432
2433
            if (!empty($coachId)) {
2434
                $values['id_coach'] = $coachId;
2435
            }
2436
2437
            if (!empty($sessionCategoryId)) {
2438
                $values['session_category_id'] = $sessionCategoryId;
2439
            }
2440
2441
            if (!empty($description)) {
2442
                $values['description'] = $description;
2443
            }
2444
2445
            if (!empty($showDescription)) {
2446
                $values['show_description'] = $showDescription;
2447
            }
2448
2449
            if (!empty($duration)) {
2450
                $values['duration'] = $duration;
2451
            }
2452
2453
            if (!empty($visibility)) {
2454
                $values['visibility'] = $visibility;
2455
            }
2456
2457
            if (!empty($promotionId)) {
2458
                $values['promotion_id'] = $promotionId;
2459
            }
2460
2461
            if (!empty($displayStartDate)) {
2462
                $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
2463
            }
2464
2465
            if (!empty($displayEndDate)) {
2466
                $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
2467
            }
2468
2469
            if (!empty($accessStartDate)) {
2470
                $values['access_start_date'] = api_get_utc_datetime($accessStartDate);
2471
            }
2472
2473
            if (!empty($accessEndDate)) {
2474
                $values['access_end_date'] = api_get_utc_datetime($accessEndDate);
2475
            }
2476
2477
            if (!empty($coachStartDate)) {
2478
                $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
2479
            }
2480
2481
            if (!empty($coachEndDate)) {
2482
                $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
2483
            }
2484
2485
            if (!empty($sendSubscriptionNotification)) {
2486
                $values['send_subscription_notification'] = $sendSubscriptionNotification;
2487
            }
2488
        }
2489
2490
        Database::update(
2491
            $tblSession,
2492
            $values,
2493
            ['id = ?' => $id]
2494
        );
2495
2496
        if (!empty($extraFields)) {
2497
            $extraFields['item_id'] = $id;
2498
            $sessionFieldValue = new ExtraFieldValue('session');
2499
            $sessionFieldValue->saveFieldValues($extraFields);
2500
        }
2501
2502
        return [
2503
            'status' => true,
2504
            'message' => get_lang('Updated'),
2505
            'id_session' => $id,
2506
        ];
2507
    }
2508
2509
    public function checkConditionalLogin(): bool
2510
    {
2511
        $file = api_get_path(SYS_CODE_PATH).'auth/conditional_login/conditional_login.php';
2512
2513
        if (!file_exists($file)) {
2514
            return true;
2515
        }
2516
2517
        include_once $file;
2518
2519
        if (!isset($login_conditions)) {
2520
            return true;
2521
        }
2522
2523
        foreach ($login_conditions as $condition) {
2524
            //If condition fails we redirect to the URL defined by the condition
2525
            if (!isset($condition['conditional_function'])) {
2526
                continue;
2527
            }
2528
2529
            $function = $condition['conditional_function'];
2530
            $result = $function(['user_id' => $this->user->getId()]);
2531
2532
            if ($result == false) {
2533
                return false;
2534
            }
2535
        }
2536
2537
        return true;
2538
    }
2539
2540
    public function getLegalConditions(): array
2541
    {
2542
        $language = api_get_language_id(
2543
            api_get_interface_language()
2544
        );
2545
2546
        $termPreview = LegalManager::get_last_condition($language);
2547
2548
        if ($termPreview) {
2549
            return $termPreview;
2550
        }
2551
2552
        $language = api_get_language_id(
2553
            api_get_setting('platformLanguage')
2554
        );
2555
2556
        $termPreview = LegalManager::get_last_condition($language);
2557
2558
        if ($termPreview) {
2559
            return $termPreview;
2560
        }
2561
2562
        $language = api_get_language_id('english');
2563
2564
        return LegalManager::get_last_condition($language);
2565
    }
2566
2567
    public function updateConditionAccepted()
2568
    {
2569
        $legalAcceptType = $_POST['legal_accept_type'] ?? null;
2570
2571
        $condArray = explode(':', $legalAcceptType);
2572
        $condArray = array_map('intval', $condArray);
2573
2574
        if (empty($condArray[0]) || empty($condArray[1])) {
2575
            return;
2576
        }
2577
2578
        $conditionToSave = intval($condArray[0]).':'.intval($condArray[1]).':'.time();
2579
2580
        LegalManager::sendEmailToUserBoss(
2581
            $this->user->getId(),
2582
            $conditionToSave
2583
        );
2584
    }
2585
2586
    public function logout()
2587
    {
2588
        online_logout($this->user->getId());
2589
2590
        Event::courseLogout(
2591
            [
2592
                'uid' => $this->user->getId(),
2593
                'cid' => $this->course ? $this->course->getId() : 0,
2594
                'sid' => $this->session ? $this->session->getId() : 0,
2595
            ]
2596
        );
2597
    }
2598
2599
    /**
2600
     * @throws Exception
2601
     */
2602
    public function setThreadNotify(int $threadId): string
2603
    {
2604
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
2605
2606
        $result = set_notification(
2607
            'thread',
2608
            $threadId,
2609
            false,
2610
            api_get_user_info($this->user->getId()),
2611
            api_get_course_info($this->course->getCode())
2612
        );
2613
2614
        if (false === $result) {
2615
            throw new Exception(get_lang('NotAllowed'));
2616
        }
2617
2618
        return $result;
2619
    }
2620
2621
    public function getCourseWorks(): array
2622
    {
2623
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2624
2625
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2626
2627
        $isAllowedToEdit = $this->user->getStatus() !== STUDENT;
2628
2629
        $courseId = $this->course->getId();
2630
        $sessionId = $this->session ? $this->session->getId() : 0;
2631
2632
        $courseInfo = api_get_course_info_by_id($this->course->getId());
2633
2634
        $works = array_filter(
2635
            getWorkListTeacherData($courseId, $sessionId, 0, 0, 0, 'title', 'ASC', ''),
2636
            function (array $work) use ($isAllowedToEdit, $courseInfo, $courseId, $sessionId) {
2637
                if (!$isAllowedToEdit
2638
                    && !userIsSubscribedToWork($this->user->getId(), $work['id'], $courseId)
2639
                ) {
2640
                    return false;
2641
                }
2642
2643
                $visibility = api_get_item_visibility($courseInfo, 'work', $work['id'], $sessionId);
2644
2645
                if (!$isAllowedToEdit && $visibility != 1) {
2646
                    return false;
2647
                }
2648
2649
                return true;
2650
            }
2651
        );
2652
2653
        return array_map(
2654
            function (array $work) use ($isAllowedToEdit, $courseInfo) {
2655
                $work['type'] = 'work.png';
2656
2657
                if (!$isAllowedToEdit) {
2658
                    $workList = get_work_user_list(
2659
                        0,
2660
                        1000,
2661
                        null,
2662
                        null,
2663
                        $work['id'],
2664
                        ' AND u.id = '.$this->user->getId()
2665
                    );
2666
2667
                    $count = getTotalWorkComment($workList, $courseInfo);
2668
                    $lastWork = getLastWorkStudentFromParentByUser($this->user->getId(), $work, $courseInfo);
2669
2670
                    $work['feedback'] = ' '.Display::label('0 '.get_lang('Feedback'), 'warning');
2671
2672
                    if (!empty($count)) {
2673
                        $work['feedback'] = ' '.Display::label($count.' '.get_lang('Feedback'), 'info');
2674
                    }
2675
2676
                    $work['last_upload'] = '';
2677
2678
                    if (!empty($lastWork)) {
2679
                        $work['last_upload'] = !empty($lastWork['qualification'])
2680
                            ? $lastWork['qualification_rounded'].' - '
2681
                            : '';
2682
                        $work['last_upload'] .= api_get_local_time($lastWork['sent_date']);
2683
                    }
2684
                }
2685
2686
                return $work;
2687
            },
2688
            $works
2689
        );
2690
    }
2691
2692
    /**
2693
     * @throws Exception
2694
     */
2695
    public function putCourseWorkVisibility(int $workId, int $status): bool
2696
    {
2697
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2698
2699
        $courseInfo = api_get_course_info_by_id($this->course->getId());
2700
2701
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2702
2703
        switch ($status) {
2704
            case 1:
2705
                return makeVisible($workId, $courseInfo);
2706
            case 0:
2707
                return makeInvisible($workId, $courseInfo);
2708
            default:
2709
                throw new Exception(get_lang('ActionNotAllowed'));
2710
        }
2711
    }
2712
2713
    public function deleteWorkStudentItem(int $workId): string
2714
    {
2715
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2716
2717
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2718
2719
        $courseInfo = api_get_course_info_by_id($this->course->getId());
2720
2721
        $fileDeleted = deleteWorkItem($workId, $courseInfo);
2722
2723
        if ($fileDeleted) {
2724
            return get_lang('TheDocumentHasBeenDeleted');
2725
        }
2726
2727
        return get_lang('YouAreNotAllowedToDeleteThisDocument');
2728
    }
2729
2730
    public function deleteWorkCorrections(int $workId): string
2731
    {
2732
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2733
2734
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2735
2736
        $courseInfo = api_get_course_info_by_id($this->course->getId());
2737
2738
        $result = get_work_user_list(null, null, null, null, $workId);
2739
2740
        if ($result) {
2741
            foreach ($result as $item) {
2742
                $workInfo = get_work_data_by_id($item['id']);
2743
2744
                deleteCorrection($courseInfo, $workInfo);
2745
            }
2746
        }
2747
2748
        return get_lang('Deleted');
2749
    }
2750
2751
    public function getWorkList(int $workId): array
2752
    {
2753
        $isAllowedToEdit = api_is_allowed_to_edit();
2754
2755
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2756
2757
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2758
2759
        $userId = $this->user->getId();
2760
        $courseId = $this->course->getId();
2761
        $sessionId = $this->session ? $this->session->getId() : 0;
2762
2763
        $courseInfo = api_get_course_info_by_id($courseId);
2764
        $webPath = api_get_path(WEB_PATH);
2765
2766
        $whereCondition = !$isAllowedToEdit ? " AND u.id = $userId" : '';
2767
2768
        $works = get_work_user_list(
2769
            0,
2770
            0,
2771
            'title',
2772
            'asc',
2773
            $workId,
2774
            $whereCondition,
2775
            null,
2776
            false,
2777
            $courseId,
2778
            $sessionId
2779
        );
2780
2781
        return array_map(
2782
            function (array $work) use ($courseInfo, $webPath) {
2783
                $itemId = $work['id'];
2784
                $count = getWorkCommentCount($itemId, $courseInfo);
2785
2786
                $work['feedback'] = $count.' '.Display::returnFontAwesomeIcon('comments-o');
2787
                $work['feedback_clean'] = $count;
2788
2789
                $workInfo = get_work_data_by_id($itemId);
2790
                $commentsTmp = getWorkComments($workInfo);
2791
                $comments = [];
2792
2793
                foreach ($commentsTmp as $comment) {
2794
                    $comment['comment'] = str_replace('src="/', 'src="'.$webPath.'app/', $comment['comment']);
2795
                    $comments[] = $comment;
2796
                }
2797
2798
                $work['comments'] = $comments;
2799
2800
                if (empty($workInfo['qualificator_id'])) {
2801
                    $qualificator_id = Display::label(get_lang('NotRevised'), 'warning');
2802
                } else {
2803
                    $qualificator_id = Display::label(get_lang('Revised'), 'success');
2804
                }
2805
2806
                $work['qualificator_id'] = $qualificator_id;
2807
2808
                return $work;
2809
            },
2810
            $works
2811
        );
2812
    }
2813
2814
    public function getWorkStudentsWithoutPublications(int $workId): array
2815
    {
2816
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2817
2818
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2819
2820
        return get_list_users_without_publication($workId);
2821
    }
2822
2823
    public function getWorkUsers(int $workId): array
2824
    {
2825
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2826
2827
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2828
2829
        $courseId = $this->course->getId();
2830
        $sessionId = $this->session ? $this->session->getId() : 0;
2831
        $courseInfo = api_get_course_info_by_id($courseId);
2832
2833
        $items = getAllUserToWork($workId, $courseId);
2834
        $usersAdded = [];
2835
        $result = [
2836
            'users_added' => [],
2837
            'users_to_add' => [],
2838
        ];
2839
2840
        if (!empty($items)) {
2841
            foreach ($items as $data) {
2842
                $usersAdded[] = $data['user_id'];
2843
2844
                $userInfo = api_get_user_info($data['user_id']);
2845
2846
                $result['users_added'][] = [
2847
                    'user_id' => (int) $data['user_id'],
2848
                    'complete_name_with_username' => $userInfo['complete_name_with_username'],
2849
                ];
2850
            }
2851
        }
2852
2853
        if (empty($sessionId)) {
2854
            $status = STUDENT;
2855
        } else {
2856
            $status = 0;
2857
        }
2858
2859
        $userList = CourseManager::get_user_list_from_course_code(
2860
            $courseInfo['code'],
2861
            $sessionId,
2862
            null,
2863
            null,
2864
            $status
2865
        );
2866
2867
        $userToAddList = [];
2868
        foreach ($userList as $user) {
2869
            if (!in_array($user['user_id'], $usersAdded)) {
2870
                $userToAddList[] = $user;
2871
            }
2872
        }
2873
2874
        if (!empty($userToAddList)) {
2875
            foreach ($userToAddList as $user) {
2876
                $userName = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].') ';
2877
2878
                $result['users_to_add'][] = [
2879
                    'user_id' => (int) $user['user_id'],
2880
                    'complete_name_with_username' => $userName,
2881
                ];
2882
            }
2883
        }
2884
2885
        return $result;
2886
    }
2887
2888
    public function getWorkStudentList(int $workId): array
2889
    {
2890
        Event::event_access_tool(TOOL_STUDENTPUBLICATION);
2891
2892
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2893
2894
        $courseId = $this->course->getId();
2895
        $courseCode = $this->course->getCode();
2896
        $sessionId = $this->session ? $this->session->getId() : 0;
2897
2898
        $myFolderData = get_work_data_by_id($workId);
2899
2900
        $workParents = [];
2901
2902
        if (empty($myFolderData)) {
2903
            $workParents = getWorkList($workId, $myFolderData);
2904
        }
2905
2906
        $workIdList = [];
2907
2908
        if (!empty($workParents)) {
2909
            foreach ($workParents as $work) {
2910
                $workIdList[] = $work->id;
2911
            }
2912
        }
2913
2914
        $userList = getWorkUserList(
2915
            $courseCode,
2916
            $sessionId,
2917
            0,
2918
            0,
2919
            null,
2920
            null,
2921
            null
2922
        );
2923
2924
        return array_map(
2925
            function ($userId) use ($courseId, $sessionId, $workParents, $workIdList) {
2926
                $user = api_get_user_info($userId);
2927
2928
                $userWorks = 0;
2929
2930
                if (!empty($workIdList)) {
2931
                    $userWorks = getUniqueStudentAttempts(
2932
                        $workIdList,
2933
                        0,
2934
                        $courseId,
2935
                        $sessionId,
2936
                        $user['user_id']
2937
                    );
2938
                }
2939
2940
                $works = $userWorks." / ".count($workParents);
2941
2942
                return [
2943
                    'id' => $userId,
2944
                    'complete_name' => api_get_person_name($user['firstname'], $user['lastname']),
2945
                    'works' => $works,
2946
                ];
2947
            },
2948
            $userList
2949
        );
2950
    }
2951
2952
    public function viewUserProfile(int $userId)
2953
    {
2954
        $url = api_get_path(WEB_CODE_PATH).'social/profile.php';
2955
2956
        if ($userId) {
2957
            $url .= '?'.http_build_query(['u' => $userId]);
2958
        }
2959
2960
        header("Location: $url");
2961
        exit;
2962
    }
2963
2964
    public function viewCourseHome()
2965
    {
2966
        $url = api_get_course_url($this->course->getCode(), $this->session ? $this->session->getId() : 0);
2967
2968
        header("Location: $url");
2969
        exit;
2970
    }
2971
2972
    public function viewDocumentInFrame(int $documentId)
2973
    {
2974
        $courseCode = $this->course->getCode();
2975
        $sessionId = $this->session ? $this->session->getId() : 0;
2976
2977
        $url = api_get_path(WEB_CODE_PATH).'document/showinframes.php?'
2978
            .http_build_query(
2979
                [
2980
                    'cidReq' => $courseCode,
2981
                    'id_session' => $sessionId,
2982
                    'gidReq' => 0,
2983
                    'gradebook' => 0,
2984
                    'origin' => self::SERVICE_NAME,
2985
                    'id' => $documentId,
2986
                ]
2987
            );
2988
2989
        header("Location: $url");
2990
        exit;
2991
    }
2992
2993
    public function viewQuizTool()
2994
    {
2995
        $courseCode = $this->course->getCode();
2996
        $sessionId = $this->session ? $this->session->getId() : 0;
2997
2998
        $url = api_get_path(WEB_CODE_PATH).'exercise/exercise.php?'
2999
            .http_build_query(
3000
                [
3001
                    'cidReq' => $courseCode,
3002
                    'id_session' => $sessionId,
3003
                    'gidReq' => 0,
3004
                    'gradebook' => 0,
3005
                    'origin' => self::SERVICE_NAME,
3006
                ]
3007
            );
3008
3009
        header("Location: $url");
3010
        exit;
3011
    }
3012
3013
    public function viewSurveyTool()
3014
    {
3015
        $courseCode = $this->course->getCode();
3016
        $sessionId = $this->session ? $this->session->getId() : 0;
3017
3018
        $url = api_get_path(WEB_CODE_PATH).'survey/survey_list.php?'
3019
            .http_build_query(
3020
                [
3021
                    'cidReq' => $courseCode,
3022
                    'id_session' => $sessionId,
3023
                    'gidReq' => 0,
3024
                    'gradebook' => 0,
3025
                    'origin' => self::SERVICE_NAME,
3026
                ]
3027
            );
3028
3029
        header("Location: $url");
3030
        exit;
3031
    }
3032
3033
    public function viewMessage(int $messageId)
3034
    {
3035
        $url = api_get_path(WEB_CODE_PATH).'messages/view_message.php?'.http_build_query(['id' => $messageId]);
3036
3037
        header("Location: $url");
3038
        exit;
3039
    }
3040
3041
    public function downloadForumPostAttachment(string $path)
3042
    {
3043
        $courseCode = $this->course->getCode();
3044
        $sessionId = $this->session ? $this->session->getId() : 0;
3045
3046
        $url = api_get_path(WEB_CODE_PATH).'forum/download.php?'
3047
            .http_build_query(
3048
                [
3049
                    'cidReq' => $courseCode,
3050
                    'id_session' => $sessionId,
3051
                    'gidReq' => 0,
3052
                    'gradebook' => 0,
3053
                    'origin' => self::SERVICE_NAME,
3054
                    'file' => Security::remove_XSS($path),
3055
                ]
3056
            );
3057
3058
        header("Location: $url");
3059
        exit;
3060
    }
3061
3062
    public function downloadWorkFolder(int $workId)
3063
    {
3064
        $cidReq = api_get_cidreq();
3065
        $url = api_get_path(WEB_CODE_PATH)."work/downloadfolder.inc.php?id=$workId&$cidReq";
3066
3067
        header("Location: $url");
3068
        exit;
3069
    }
3070
3071
    public function downloadWorkCommentAttachment(int $commentId)
3072
    {
3073
        $cidReq = api_get_cidreq();
3074
        $url = api_get_path(WEB_CODE_PATH)."work/download_comment_file.php?comment_id=$commentId&$cidReq";
3075
3076
        header("Location: $url");
3077
        exit;
3078
    }
3079
3080
    public function downloadWork(int $workId, bool $isCorrection = false)
3081
    {
3082
        $cidReq = api_get_cidreq();
3083
        $url = api_get_path(WEB_CODE_PATH)."work/download.php?$cidReq&"
3084
            .http_build_query(
3085
                [
3086
                    'id' => $workId,
3087
                    'correction' => $isCorrection ? 1 : null,
3088
                ]
3089
            );
3090
3091
        header("Location: $url");
3092
        exit;
3093
    }
3094
3095
    /**
3096
     * @throws Exception
3097
     */
3098
    public function getAllUsersApiKeys(int $page, int $length, ?int $urlId = null): array
3099
    {
3100
        if (false === api_get_configuration_value('webservice_enable_adminonly_api')
3101
            || !UserManager::is_admin($this->user->getId())
3102
        ) {
3103
            throw new Exception(get_lang('NotAllowed'));
3104
        }
3105
3106
        $limitOffset = ($page - 1) * $length;
3107
3108
        $currentUrlId = $urlId ?: api_get_current_access_url_id();
3109
3110
        $data = [];
3111
        $data['total'] = UserManager::get_number_of_users(0, $currentUrlId);
3112
        $data['list'] = array_map(
3113
            function (array $user) {
3114
                $apiKeys = UserManager::get_api_keys($user['id'], self::SERVICE_NAME);
3115
3116
                return [
3117
                    'id' => $user['id'],
3118
                    'username' => $user['username'],
3119
                    'api_key' => $apiKeys ? current($apiKeys) : null,
3120
                ];
3121
            },
3122
            $users = UserManager::get_user_list([], [], $limitOffset, $length, $currentUrlId)
3123
        );
3124
        $data['length'] = count($users);
3125
3126
        if ($page * $length < $data['total']) {
3127
            $nextPageQueryParams = [
3128
                'page' => $page + 1,
3129
                'per_page' => $length,
3130
                'url_id' => $urlId,
3131
            ];
3132
3133
            $data['next'] = $this->generateUrl($nextPageQueryParams);
3134
        }
3135
3136
        return $data;
3137
    }
3138
3139
    /**
3140
     * @throws Exception
3141
     */
3142
    public function getUserApiKey(string $username): array
3143
    {
3144
        if (false === api_get_configuration_value('webservice_enable_adminonly_api')
3145
            || !UserManager::is_admin($this->user->getId())
3146
        ) {
3147
            throw new Exception(get_lang('NotAllowed'));
3148
        }
3149
3150
        $userInfo = api_get_user_info_from_username($username);
3151
3152
        if (empty($userInfo)) {
3153
            throw new Exception(get_lang('UserNotFound'));
3154
        }
3155
3156
        $apiKeys = UserManager::get_api_keys($userInfo['id'], self::SERVICE_NAME);
3157
3158
        return [
3159
            'id' => $userInfo['id'],
3160
            'username' => $userInfo['username'],
3161
            'api_key' => $apiKeys ? current($apiKeys) : null,
3162
        ];
3163
    }
3164
3165
    public static function isAllowedByRequest(bool $inpersonate = false): bool
3166
    {
3167
        $username = $_GET['username'] ?? null;
3168
        $apiKey = $_GET['api_key'] ?? null;
3169
3170
        if (empty($username) || empty($apiKey)) {
3171
            return false;
3172
        }
3173
3174
        try {
3175
            $restApi = self::validate($username, $apiKey);
3176
        } catch (Exception $e) {
3177
            return false;
3178
        }
3179
3180
        if ($inpersonate) {
3181
            Login::init_user($restApi->getUser()->getId(), true);
3182
        }
3183
3184
        return (bool) $restApi;
3185
    }
3186
3187
    /**
3188
     * @param array $additionalParams Optional
3189
     *
3190
     * @return string
3191
     */
3192
    private function encodeParams(array $additionalParams = [])
3193
    {
3194
        $params = array_merge(
3195
            $additionalParams,
3196
            [
3197
                'api_key' => $this->apiKey,
3198
                'username' => $this->user->getUsername(),
3199
            ]
3200
        );
3201
3202
        return json_encode($params);
3203
    }
3204
3205
    private function generateUrl(array $additionalParams = []): string
3206
    {
3207
        $queryParams = [
3208
            'course' => $this->course ? $this->course->getId() : null,
3209
            'session' => $this->session ? $this->session->getId() : null,
3210
            'api_key' => $this->apiKey,
3211
            'username' => $this->user->getUsername(),
3212
        ];
3213
3214
        return api_get_self().'?'
3215
            .http_build_query(array_merge($queryParams, $additionalParams));
3216
    }
3217
}
3218