Passed
Push — 1.11.x ( 06bf6a...661027 )
by Angel Fernando Quiroz
10:04
created

Rest::getSessionFromExtraField()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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