Passed
Push — 1.11.x ( fccf1b...e4b58b )
by Angel Fernando Quiroz
13:48
created

Rest::updateSession()   F

Complexity

Conditions 36
Paths > 20000

Size

Total Lines 141
Code Lines 91

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 36
eloc 91
c 2
b 0
f 0
nc 262672
nop 1
dl 0
loc 141
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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