Passed
Push — 1.11.x ( 18569f...dac68b )
by Julito
14:22
created

Rest::unSubscribeUserToCourse()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 19
rs 9.6111
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 GET_USER_MESSAGES = 'user_messages';
23
    const POST_USER_MESSAGE_READ = 'user_message_read';
24
    const POST_USER_MESSAGE_UNREAD = 'user_message_unread';
25
    const SAVE_GCM_ID = 'gcm_id';
26
    const GET_USER_COURSES = 'user_courses';
27
    const GET_PROFILE = 'user_profile';
28
    const GET_COURSE_INFO = 'course_info';
29
    const GET_COURSE_DESCRIPTIONS = 'course_descriptions';
30
    const GET_COURSE_DOCUMENTS = 'course_documents';
31
    const GET_COURSE_ANNOUNCEMENTS = 'course_announcements';
32
    const GET_COURSE_ANNOUNCEMENT = 'course_announcement';
33
    const GET_COURSE_AGENDA = 'course_agenda';
34
    const GET_COURSE_NOTEBOOKS = 'course_notebooks';
35
    const GET_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
36
    const GET_COURSE_FORUM = 'course_forum';
37
    const GET_COURSE_FORUM_THREAD = 'course_forumthread';
38
    const GET_COURSE_LEARNPATHS = 'course_learnpaths';
39
    const GET_COURSE_LEARNPATH = 'course_learnpath';
40
    const GET_COURSE_LP_PROGRESS = 'course_lp_progress';
41
    const SAVE_FORUM_POST = 'save_forum_post';
42
    const GET_USER_SESSIONS = 'user_sessions';
43
    const SAVE_USER_MESSAGE = 'save_user_message';
44
    const GET_MESSAGE_USERS = 'message_users';
45
    const SAVE_COURSE_NOTEBOOK = 'save_course_notebook';
46
    const SAVE_FORUM_THREAD = 'save_forum_thread';
47
    const SAVE_COURSE = 'save_course';
48
    const SAVE_USER = 'save_user';
49
    const SAVE_USER_JSON = 'save_user_json';
50
    const SUBSCRIBE_USER_TO_COURSE = 'subscribe_user_to_course';
51
    const UNSUBSCRIBE_USER_TO_COURSE = 'unsubscribe_user_to_course';
52
    const EXTRAFIELD_GCM_ID = 'gcm_registration_id';
53
    const GET_USER_MESSAGES_RECEIVED = 'user_messages_received';
54
    const GET_USER_MESSAGES_SENT = 'user_messages_sent';
55
    const DELETE_USER_MESSAGE = 'delete_user_message';
56
    const SET_MESSAGE_READ = 'set_message_read';
57
    const CREATE_CAMPUS = 'add_campus';
58
    const EDIT_CAMPUS = 'edit_campus';
59
    const DELETE_CAMPUS = 'delete_campus';
60
    const SAVE_SESSION = 'save_session';
61
    const GET_USERS = 'get_users';
62
    const GET_COURSES = 'get_courses';
63
    const GET_COURSES_FROM_EXTRA_FIELD = 'get_courses_from_extra_field';
64
    const ADD_COURSES_SESSION = 'add_courses_session';
65
    const ADD_USERS_SESSION = 'add_users_session';
66
    const CREATE_SESSION_FROM_MODEL = 'create_session_from_model';
67
    const SUBSCRIBE_USER_TO_SESSION_FROM_USERNAME = 'subscribe_user_to_session_from_username';
68
    const GET_SESSION_FROM_EXTRA_FIELD = 'get_session_from_extra_field';
69
    const UPDATE_USER_FROM_USERNAME = 'update_user_from_username';
70
    const USERNAME_EXIST = 'username_exist';
71
    const GET_COURSE_QUIZ_MDL_COMPAT = 'get_course_quiz_mdl_compat';
72
    const UPDATE_USER_PAUSE_TRAINING = 'update_user_pause_training';
73
    const DELETE_COURSE = 'delete_course';
74
75
    /**
76
     * @var Session
77
     */
78
    private $session;
79
80
    /**
81
     * @var Course
82
     */
83
    private $course;
84
85
    /**
86
     * Rest constructor.
87
     *
88
     * @param string $username
89
     * @param string $apiKey
90
     */
91
    public function __construct($username, $apiKey)
92
    {
93
        parent::__construct($username, $apiKey);
94
    }
95
96
    /**
97
     * @param string $username
98
     * @param string $apiKeyToValidate
99
     *
100
     * @throws Exception
101
     *
102
     * @return Rest
103
     */
104
    public static function validate($username, $apiKeyToValidate)
105
    {
106
        $apiKey = self::findUserApiKey($username, self::SERVICE_NAME);
107
108
        if ($apiKey != $apiKeyToValidate) {
109
            throw new Exception(get_lang('InvalidApiKey'));
110
        }
111
112
        return new self($username, $apiKey);
113
    }
114
115
    /**
116
     * Create the gcm_registration_id extra field for users.
117
     */
118
    public static function init()
119
    {
120
        $extraField = new ExtraField('user');
121
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION);
122
123
        if (empty($fieldInfo)) {
124
            $extraField->save(
125
                [
126
                    'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
127
                    'field_type' => ExtraField::FIELD_TYPE_TEXT,
128
                    'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION,
129
                ]
130
            );
131
        }
132
    }
133
134
    /**
135
     * @param string $encoded
136
     *
137
     * @return array
138
     */
139
    public static function decodeParams($encoded)
140
    {
141
        return json_decode($encoded);
142
    }
143
144
    /**
145
     * Set the current course.
146
     *
147
     * @param int $id
148
     *
149
     * @throws Exception
150
     */
151
    public function setCourse($id)
152
    {
153
        if (!$id) {
154
            $this->course = null;
155
156
            return;
157
        }
158
159
        $em = Database::getManager();
160
        /** @var Course $course */
161
        $course = $em->find('ChamiloCoreBundle:Course', $id);
162
163
        if (!$course) {
0 ignored issues
show
introduced by
$course is of type Chamilo\CoreBundle\Entity\Course, thus it always evaluated to true.
Loading history...
164
            throw new Exception(get_lang('NoCourse'));
165
        }
166
167
        $this->course = $course;
168
    }
169
170
    /**
171
     * Set the current session.
172
     *
173
     * @param int $id
174
     *
175
     * @throws Exception
176
     */
177
    public function setSession($id)
178
    {
179
        if (!$id) {
180
            $this->session = null;
181
182
            return;
183
        }
184
185
        $em = Database::getManager();
186
        /** @var Session $session */
187
        $session = $em->find('ChamiloCoreBundle:Session', $id);
188
189
        if (!$session) {
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
190
            throw new Exception(get_lang('NoSession'));
191
        }
192
193
        $this->session = $session;
194
    }
195
196
    /**
197
     * @param string $registrationId
198
     *
199
     * @return bool
200
     */
201
    public function setGcmId($registrationId)
202
    {
203
        $registrationId = Security::remove_XSS($registrationId);
204
        $extraFieldValue = new ExtraFieldValue('user');
205
206
        return $extraFieldValue->save(
207
            [
208
                'variable' => self::EXTRA_FIELD_GCM_REGISTRATION,
209
                'value' => $registrationId,
210
                'item_id' => $this->user->getId(),
211
            ]
212
        );
213
    }
214
215
    /**
216
     * @param int $lastMessageId
217
     *
218
     * @return array
219
     */
220
    public function getUserMessages($lastMessageId = 0)
221
    {
222
        $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId);
223
        $messages = [];
224
225
        foreach ($lastMessages as $message) {
226
            $hasAttachments = MessageManager::hasAttachments($message['id']);
227
228
            $messages[] = [
229
                'id' => $message['id'],
230
                'title' => $message['title'],
231
                'sender' => [
232
                    'id' => $message['user_id'],
233
                    'lastname' => $message['lastname'],
234
                    'firstname' => $message['firstname'],
235
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
236
                ],
237
                'sendDate' => $message['send_date'],
238
                'content' => $message['content'],
239
                'hasAttachments' => $hasAttachments,
240
                'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?'
241
                    .http_build_query(['type' => 1, 'id' => $message['id']]),
242
            ];
243
        }
244
245
        return $messages;
246
    }
247
248
    /**
249
     * @return array
250
     */
251
    public function getUserReceivedMessages()
252
    {
253
        $lastMessages = MessageManager::getReceivedMessages($this->user->getId(), 0);
254
        $messages = [];
255
256
        foreach ($lastMessages as $message) {
257
            $hasAttachments = MessageManager::hasAttachments($message['id']);
258
            $attachmentList = [];
259
            if ($hasAttachments) {
260
                $attachmentList = MessageManager::getAttachmentList($message['id']);
261
            }
262
            $messages[] = [
263
                'id' => $message['id'],
264
                'title' => $message['title'],
265
                'msgStatus' => $message['msg_status'],
266
                'sender' => [
267
                    'id' => $message['user_id'],
268
                    'lastname' => $message['lastname'],
269
                    'firstname' => $message['firstname'],
270
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
271
                    'pictureUri' => $message['pictureUri'],
272
                ],
273
                'sendDate' => $message['send_date'],
274
                'content' => $message['content'],
275
                'hasAttachments' => $hasAttachments,
276
                'attachmentList' => $attachmentList,
277
                'url' => '',
278
            ];
279
        }
280
281
        return $messages;
282
    }
283
284
    /**
285
     * @return array
286
     */
287
    public function getUserSentMessages()
288
    {
289
        $lastMessages = MessageManager::getSentMessages($this->user->getId(), 0);
290
        $messages = [];
291
292
        foreach ($lastMessages as $message) {
293
            $hasAttachments = MessageManager::hasAttachments($message['id']);
294
295
            $messages[] = [
296
                'id' => $message['id'],
297
                'title' => $message['title'],
298
                'msgStatus' => $message['msg_status'],
299
                'receiver' => [
300
                    'id' => $message['user_id'],
301
                    'lastname' => $message['lastname'],
302
                    'firstname' => $message['firstname'],
303
                    'completeName' => api_get_person_name($message['firstname'], $message['lastname']),
304
                    'pictureUri' => $message['pictureUri'],
305
                ],
306
                'sendDate' => $message['send_date'],
307
                'content' => $message['content'],
308
                'hasAttachments' => $hasAttachments,
309
                'url' => '',
310
            ];
311
        }
312
313
        return $messages;
314
    }
315
316
    /**
317
     * Get the user courses.
318
     */
319
    public function getUserCourses($userId = 0): array
320
    {
321
        if (empty($userId)) {
322
            $userId = $this->user->getId();
323
        }
324
325
        $courses = CourseManager::get_courses_list_by_user_id($userId);
326
        $data = [];
327
328
        foreach ($courses as $courseInfo) {
329
            /** @var Course $course */
330
            $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseInfo['real_id']);
331
            $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode());
332
            $picturePath = CourseManager::getPicturePath($course, true)
333
                ?: Display::return_icon('session_default.png', null, null, null, null, true);
334
335
            $data[] = [
336
                'id' => $course->getId(),
337
                'title' => $course->getTitle(),
338
                'code' => $course->getCode(),
339
                'directory' => $course->getDirectory(),
340
                'urlPicture' => $picturePath,
341
                'teachers' => $teachers,
342
                'isSpecial' => !empty($courseInfo['special_course']),
343
            ];
344
        }
345
346
        return $data;
347
    }
348
349
    /**
350
     * @throws Exception
351
     *
352
     * @return array
353
     */
354
    public function getCourseInfo()
355
    {
356
        $teachers = CourseManager::getTeacherListFromCourseCodeToString($this->course->getCode());
357
        $tools = CourseHome::get_tools_category(
358
            TOOL_STUDENT_VIEW,
359
            $this->course->getId(),
360
            $this->session ? $this->session->getId() : 0
361
        );
362
363
        return [
364
            'id' => $this->course->getId(),
365
            'title' => $this->course->getTitle(),
366
            'code' => $this->course->getCode(),
367
            'directory' => $this->course->getDirectory(),
368
            'urlPicture' => CourseManager::getPicturePath($this->course, true),
369
            'teachers' => $teachers,
370
            'tools' => array_map(
371
                function ($tool) {
372
                    return ['type' => $tool['name']];
373
                },
374
                $tools
375
            ),
376
        ];
377
    }
378
379
    /**
380
     * Get the course descriptions.
381
     *
382
     * @throws Exception
383
     *
384
     * @return array
385
     */
386
    public function getCourseDescriptions()
387
    {
388
        $descriptions = CourseDescription::get_descriptions($this->course->getId());
389
        $results = [];
390
391
        /** @var CourseDescription $description */
392
        foreach ($descriptions as $description) {
393
            $results[] = [
394
                'id' => $description->get_description_type(),
395
                'title' => $description->get_title(),
396
                'content' => str_replace('src="/', 'src="'.api_get_path(WEB_PATH), $description->get_content()),
397
            ];
398
        }
399
400
        return $results;
401
    }
402
403
    /**
404
     * @param int $directoryId
405
     *
406
     * @throws Exception
407
     *
408
     * @return array
409
     */
410
    public function getCourseDocuments($directoryId = 0)
411
    {
412
        /** @var string $path */
413
        $path = '/';
414
        $sessionId = $this->session ? $this->session->getId() : 0;
415
416
        if ($directoryId) {
417
            $directory = DocumentManager::get_document_data_by_id(
418
                $directoryId,
419
                $this->course->getCode(),
420
                false,
421
                $sessionId
422
            );
423
424
            if (!$directory) {
425
                throw new Exception('NoDataAvailable');
426
            }
427
428
            $path = $directory['path'];
429
        }
430
431
        $courseInfo = api_get_course_info_by_id($this->course->getId());
432
        $documents = DocumentManager::getAllDocumentData(
433
            $courseInfo,
434
            $path,
435
            0,
436
            null,
437
            false,
438
            false,
439
            $sessionId
440
        );
441
        $results = [];
442
443
        if (!empty($documents)) {
444
            $webPath = api_get_path(WEB_CODE_PATH).'document/document.php?';
445
446
            /** @var array $document */
447
            foreach ($documents as $document) {
448
                if ($document['visibility'] != '1') {
449
                    continue;
450
                }
451
452
                $icon = $document['filetype'] == 'file'
453
                    ? choose_image($document['path'])
454
                    : chooseFolderIcon($document['path']);
455
456
                $results[] = [
457
                    'id' => $document['id'],
458
                    'type' => $document['filetype'],
459
                    'title' => $document['title'],
460
                    'path' => $document['path'],
461
                    'url' => $webPath.http_build_query(
462
                        [
463
                            'username' => $this->user->getUsername(),
464
                            'api_key' => $this->apiKey,
465
                            'cidReq' => $this->course->getCode(),
466
                            'id_session' => $sessionId,
467
                            'gidReq' => 0,
468
                            'gradebook' => 0,
469
                            'origin' => '',
470
                            'action' => 'download',
471
                            'id' => $document['id'],
472
                        ]
473
                    ),
474
                    'icon' => $icon,
475
                    'size' => format_file_size($document['size']),
476
                ];
477
            }
478
        }
479
480
        return $results;
481
    }
482
483
    /**
484
     * @throws Exception
485
     *
486
     * @return array
487
     */
488
    public function getCourseAnnouncements()
489
    {
490
        $sessionId = $this->session ? $this->session->getId() : 0;
491
492
        $announcements = AnnouncementManager::getAnnouncements(
493
            null,
494
            null,
495
            false,
496
            null,
497
            null,
498
            null,
499
            null,
500
            null,
501
            0,
502
            $this->user->getId(),
503
            $this->course->getId(),
504
            $sessionId
505
        );
506
507
        $announcements = array_map(
508
            function ($announcement) {
509
                return [
510
                    'id' => (int) $announcement['id'],
511
                    'title' => strip_tags($announcement['title']),
512
                    'creatorName' => strip_tags($announcement['username']),
513
                    'date' => strip_tags($announcement['insert_date']),
514
                ];
515
            },
516
            $announcements
517
        );
518
519
        return $announcements;
520
    }
521
522
    /**
523
     * @param int $announcementId
524
     *
525
     * @throws Exception
526
     *
527
     * @return array
528
     */
529
    public function getCourseAnnouncement($announcementId)
530
    {
531
        $sessionId = $this->session ? $this->session->getId() : 0;
532
        $announcement = AnnouncementManager::getAnnouncementInfoById(
533
            $announcementId,
534
            $this->course->getId(),
535
            $this->user->getId()
536
        );
537
538
        if (!$announcement) {
539
            throw new Exception(get_lang('NoAnnouncement'));
540
        }
541
542
        return [
543
            'id' => $announcement['announcement']->getIid(),
544
            'title' => $announcement['announcement']->getTitle(),
545
            'creatorName' => UserManager::formatUserFullName($announcement['item_property']->getInsertUser()),
546
            'date' => api_convert_and_format_date(
547
                $announcement['item_property']->getInsertDate(),
548
                DATE_TIME_FORMAT_LONG_24H
549
            ),
550
            'content' => AnnouncementManager::parseContent(
551
                $this->user->getId(),
552
                $announcement['announcement']->getContent(),
553
                $this->course->getCode(),
554
                $sessionId
555
            ),
556
        ];
557
    }
558
559
    /**
560
     * @throws Exception
561
     *
562
     * @return array
563
     */
564
    public function getCourseAgenda()
565
    {
566
        $sessionId = $this->session ? $this->session->getId() : 0;
567
568
        $agenda = new Agenda(
569
            'course',
570
            $this->user->getId(),
571
            $this->course->getId(),
572
            $sessionId
573
        );
574
        $result = $agenda->parseAgendaFilter(null);
575
576
        $start = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
577
        $start->modify('first day of this month');
578
        $start->setTime(0, 0, 0);
579
        $end = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
580
        $end->modify('last day of this month');
581
        $end->setTime(23, 59, 59);
582
583
        $groupId = current($result['groups']);
584
        $userId = current($result['users']);
585
586
        $events = $agenda->getEvents(
587
            $start->getTimestamp(),
588
            $end->getTimestamp(),
589
            $this->course->getId(),
590
            $groupId,
591
            $userId,
592
            'array'
593
        );
594
595
        if (!is_array($events)) {
596
            return [];
597
        }
598
599
        $webPath = api_get_path(WEB_PATH);
600
601
        return array_map(
602
            function ($event) use ($webPath) {
603
                return [
604
                    'id' => (int) $event['unique_id'],
605
                    'title' => $event['title'],
606
                    'content' => str_replace('src="/', 'src="'.$webPath, $event['description']),
607
                    'startDate' => $event['start_date_localtime'],
608
                    'endDate' => $event['end_date_localtime'],
609
                    'isAllDay' => $event['allDay'] ? true : false,
610
                ];
611
            },
612
            $events
613
        );
614
    }
615
616
    /**
617
     * @throws Exception
618
     *
619
     * @return array
620
     */
621
    public function getCourseNotebooks()
622
    {
623
        $em = Database::getManager();
624
        /** @var CNotebookRepository $notebooksRepo */
625
        $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook');
626
        $notebooks = $notebooksRepo->findByUser($this->user, $this->course, $this->session);
627
628
        return array_map(
629
            function (CNotebook $notebook) {
630
                return [
631
                    'id' => $notebook->getIid(),
632
                    'title' => $notebook->getTitle(),
633
                    'description' => $notebook->getDescription(),
634
                    'creationDate' => api_format_date(
635
                        $notebook->getCreationDate()->getTimestamp()
636
                    ),
637
                    'updateDate' => api_format_date(
638
                        $notebook->getUpdateDate()->getTimestamp()
639
                    ),
640
                ];
641
            },
642
            $notebooks
643
        );
644
    }
645
646
    /**
647
     * @throws Exception
648
     *
649
     * @return array
650
     */
651
    public function getCourseForumCategories()
652
    {
653
        $sessionId = $this->session ? $this->session->getId() : 0;
654
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
655
656
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
657
658
        $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId);
659
        $categories = [];
660
        $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true';
661
        $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId);
662
        $forums = [];
663
664
        foreach ($forumsFullData as $forumId => $forumInfo) {
665
            $forum = [
666
                'id' => (int) $forumInfo['iid'],
667
                'catId' => (int) $forumInfo['forum_category'],
668
                'title' => $forumInfo['forum_title'],
669
                'description' => $forumInfo['forum_comment'],
670
                'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
671
                'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval(
672
                    $forumInfo['number_of_threads']
673
                ) : 0,
674
                'lastPost' => null,
675
            ];
676
677
            $lastPostInfo = get_last_post_information($forumId, false, $this->course->getId(), $sessionId);
678
679
            if ($lastPostInfo) {
680
                $forum['lastPost'] = [
681
                    'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
682
                    'user' => api_get_person_name(
683
                        $lastPostInfo['last_poster_firstname'],
684
                        $lastPostInfo['last_poster_lastname']
685
                    ),
686
                ];
687
            }
688
689
            $forums[] = $forum;
690
        }
691
692
        foreach ($categoriesFullData as $category) {
693
            $categoryForums = array_filter(
694
                $forums,
695
                function (array $forum) use ($category) {
696
                    if ($forum['catId'] != $category['cat_id']) {
697
                        return false;
698
                    }
699
700
                    return true;
701
                }
702
            );
703
704
            $categories[] = [
705
                'id' => (int) $category['iid'],
706
                'title' => $category['cat_title'],
707
                'catId' => (int) $category['cat_id'],
708
                'description' => $category['cat_comment'],
709
                'forums' => $categoryForums,
710
                'courseId' => $this->course->getId(),
711
            ];
712
        }
713
714
        return $categories;
715
    }
716
717
    /**
718
     * @param int $forumId
719
     *
720
     * @throws Exception
721
     *
722
     * @return array
723
     */
724
    public function getCourseForum($forumId)
725
    {
726
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
727
728
        $sessionId = $this->session ? $this->session->getId() : 0;
729
        $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId);
730
731
        if (!isset($forumInfo['iid'])) {
732
            throw new Exception(get_lang('NoForum'));
733
        }
734
735
        $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/';
736
        $forum = [
737
            'id' => $forumInfo['iid'],
738
            'title' => $forumInfo['forum_title'],
739
            'description' => $forumInfo['forum_comment'],
740
            'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '',
741
            'threads' => [],
742
        ];
743
744
        $threads = get_threads($forumInfo['iid'], $this->course->getId(), $sessionId);
745
746
        foreach ($threads as $thread) {
747
            $forum['threads'][] = [
748
                'id' => $thread['iid'],
749
                'title' => $thread['thread_title'],
750
                'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H),
751
                'numberOfReplies' => $thread['thread_replies'],
752
                'numberOfViews' => $thread['thread_views'],
753
                'author' => api_get_person_name($thread['firstname'], $thread['lastname']),
754
            ];
755
        }
756
757
        return $forum;
758
    }
759
760
    /**
761
     * @param int $forumId
762
     * @param int $threadId
763
     *
764
     * @return array
765
     */
766
    public function getCourseForumThread($forumId, $threadId)
767
    {
768
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
769
770
        $sessionId = $this->session ? $this->session->getId() : 0;
771
        $threadInfo = get_thread_information($forumId, $threadId, $sessionId);
772
773
        $thread = [
774
            'id' => intval($threadInfo['iid']),
775
            'cId' => intval($threadInfo['c_id']),
776
            'title' => $threadInfo['thread_title'],
777
            'forumId' => intval($threadInfo['forum_id']),
778
            'posts' => [],
779
        ];
780
781
        $forumInfo = get_forums($threadInfo['forum_id'], $this->course->getCode(), true, $sessionId);
782
        $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC');
783
784
        foreach ($postsInfo as $postInfo) {
785
            $thread['posts'][] = [
786
                'id' => $postInfo['iid'],
787
                'title' => $postInfo['post_title'],
788
                'text' => $postInfo['post_text'],
789
                'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']),
790
                'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H),
791
                'parentId' => $postInfo['post_parent_id'],
792
            ];
793
        }
794
795
        return $thread;
796
    }
797
798
    /**
799
     * @return array
800
     */
801
    public function getUserProfile()
802
    {
803
        $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web');
804
805
        $result = [
806
            'pictureUri' => $pictureInfo['dir'].$pictureInfo['file'],
807
            'id' => $this->user->getId(),
808
            'status' => $this->user->getStatus(),
809
            'fullName' => UserManager::formatUserFullName($this->user),
810
            'username' => $this->user->getUsername(),
811
            'officialCode' => $this->user->getOfficialCode(),
812
            'phone' => $this->user->getPhone(),
813
            'extra' => [],
814
        ];
815
816
        $fieldValue = new ExtraFieldValue('user');
817
        $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true);
818
819
        foreach ($extraInfo as $extra) {
820
            /** @var ExtraFieldValues $extraValue */
821
            $extraValue = $extra['value'];
822
            $result['extra'][] = [
823
                'title' => $extraValue->getField()->getDisplayText(true),
824
                'value' => $extraValue->getValue(),
825
            ];
826
        }
827
828
        return $result;
829
    }
830
831
    public function getCourseLpProgress()
832
    {
833
        $sessionId = $this->session ? $this->session->getId() : 0;
834
        $userId = $this->user->getId();
835
836
        /*$sessionId = $this->session ? $this->session->getId() : 0;
837
        $courseId = $this->course->getId();*/
838
839
        $result = Tracking::getCourseLpProgress($userId, $sessionId);
840
841
        return [$result];
842
    }
843
844
    /**
845
     * @throws Exception
846
     *
847
     * @return array
848
     */
849
    public function getCourseLearnPaths()
850
    {
851
        $sessionId = $this->session ? $this->session->getId() : 0;
852
        $categoriesTempList = learnpath::getCategories($this->course->getId());
853
854
        $categoryNone = new CLpCategory();
855
        $categoryNone->setId(0);
856
        $categoryNone->setName(get_lang('WithOutCategory'));
857
        $categoryNone->setPosition(0);
858
859
        $categories = array_merge([$categoryNone], $categoriesTempList);
860
        $categoryData = [];
861
862
        /** @var CLpCategory $category */
863
        foreach ($categories as $category) {
864
            $learnPathList = new LearnpathList(
865
                $this->user->getId(),
866
                api_get_course_info($this->course->getCode()),
867
                $sessionId,
868
                null,
869
                false,
870
                $category->getId()
871
            );
872
873
            $flatLpList = $learnPathList->get_flat_list();
874
875
            if (empty($flatLpList)) {
876
                continue;
877
            }
878
879
            $listData = [];
880
881
            foreach ($flatLpList as $lpId => $lpDetails) {
882
                if ($lpDetails['lp_visibility'] == 0) {
883
                    continue;
884
                }
885
886
                if (!learnpath::is_lp_visible_for_student(
887
                    $lpId,
888
                    $this->user->getId(),
889
                    api_get_course_info($this->course->getCode()),
890
                    $sessionId
891
                )) {
892
                    continue;
893
                }
894
895
                $timeLimits = false;
896
897
                // This is an old LP (from a migration 1.8.7) so we do nothing
898
                if (empty($lpDetails['created_on']) && empty($lpDetails['modified_on'])) {
899
                    $timeLimits = false;
900
                }
901
902
                // Checking if expired_on is ON
903
                if (!empty($lpDetails['expired_on'])) {
904
                    $timeLimits = true;
905
                }
906
907
                if ($timeLimits) {
908
                    if (!empty($lpDetails['publicated_on']) && !empty($lpDetails['expired_on'])) {
909
                        $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC');
910
                        $endTime = api_strtotime($lpDetails['expired_on'], 'UTC');
911
                        $now = time();
912
                        $isActiveTime = false;
913
914
                        if ($now > $startTime && $endTime > $now) {
915
                            $isActiveTime = true;
916
                        }
917
918
                        if (!$isActiveTime) {
919
                            continue;
920
                        }
921
                    }
922
                }
923
924
                $progress = learnpath::getProgress($lpId, $this->user->getId(), $this->course->getId(), $sessionId);
925
926
                $listData[] = [
927
                    'id' => $lpId,
928
                    'title' => Security::remove_XSS($lpDetails['lp_name']),
929
                    'progress' => $progress,
930
                    'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query(
931
                        [
932
                            'hash' => $this->encodeParams(
933
                                [
934
                                    'action' => 'course_learnpath',
935
                                    'lp_id' => $lpId,
936
                                    'course' => $this->course->getId(),
937
                                    'session' => $sessionId,
938
                                ]
939
                            ),
940
                        ]
941
                    ),
942
                ];
943
            }
944
945
            if (empty($listData)) {
946
                continue;
947
            }
948
949
            $categoryData[] = [
950
                'id' => $category->getId(),
951
                'name' => $category->getName(),
952
                'learnpaths' => $listData,
953
            ];
954
        }
955
956
        return $categoryData;
957
    }
958
959
    /**
960
     * Start login for a user. Then make a redirect to show the learnpath.
961
     *
962
     * @param int $lpId
963
     */
964
    public function showLearningPath($lpId)
965
    {
966
        $loggedUser['user_id'] = $this->user->getId();
967
        $loggedUser['status'] = $this->user->getStatus();
968
        $loggedUser['uidReset'] = true;
969
        $sessionId = $this->session ? $this->session->getId() : 0;
970
971
        ChamiloSession::write('_user', $loggedUser);
972
        Login::init_user($this->user->getId(), true);
973
974
        $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query(
975
            [
976
                'cidReq' => $this->course->getCode(),
977
                'id_session' => $sessionId,
978
                'gidReq' => 0,
979
                'gradebook' => 0,
980
                'origin' => '',
981
                'action' => 'view',
982
                'lp_id' => (int) $lpId,
983
                'isStudentView' => 'true',
984
            ]
985
        );
986
987
        header("Location: $url");
988
        exit;
989
    }
990
991
    /**
992
     * @param int $forumId
993
     *
994
     * @return array
995
     */
996
    public function saveForumPost(array $postValues, $forumId)
997
    {
998
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
999
1000
        $forum = get_forums($forumId, $this->course->getCode());
1001
        store_reply($forum, $postValues, $this->course->getId(), $this->user->getId());
1002
1003
        return [
1004
            'registered' => true,
1005
        ];
1006
    }
1007
1008
    /**
1009
     * Get the list of sessions for current user.
1010
     *
1011
     * @return array the sessions list
1012
     */
1013
    public function getUserSessions()
1014
    {
1015
        $data = [];
1016
        $sessionsByCategory = UserManager::get_sessions_by_category($this->user->getId(), false);
1017
1018
        foreach ($sessionsByCategory as $category) {
1019
            $categorySessions = [];
1020
1021
            foreach ($category['sessions'] as $sessions) {
1022
                $sessionCourses = [];
1023
1024
                foreach ($sessions['courses'] as $course) {
1025
                    $courseInfo = api_get_course_info_by_id($course['real_id']);
1026
                    $teachers = SessionManager::getCoachesByCourseSessionToString(
1027
                        $sessions['session_id'],
1028
                        $course['real_id']
1029
                    );
1030
1031
                    $sessionCourses[] = [
1032
                        'id' => $courseInfo['real_id'],
1033
                        'title' => $courseInfo['title'],
1034
                        'code' => $courseInfo['code'],
1035
                        'directory' => $courseInfo['directory'],
1036
                        'pictureUrl' => $courseInfo['course_image_large'],
1037
                        'urlPicture' => $courseInfo['course_image_large'],
1038
                        'teachers' => $teachers,
1039
                    ];
1040
                }
1041
1042
                $sessionBox = Display::getSessionTitleBox($sessions['session_id']);
1043
1044
                $categorySessions[] = [
1045
                    'name' => $sessionBox['title'],
1046
                    'id' => $sessions['session_id'],
1047
                    'date' => $sessionBox['dates'],
1048
                    'duration' => isset($sessionBox['duration']) ? $sessionBox['duration'] : null,
1049
                    'courses' => $sessionCourses,
1050
                ];
1051
            }
1052
1053
            $data[] = [
1054
                'id' => $category['session_category']['id'],
1055
                'name' => $category['session_category']['name'],
1056
                'sessions' => $categorySessions,
1057
            ];
1058
        }
1059
1060
        return $data;
1061
    }
1062
1063
    /**
1064
     * @param string $subject
1065
     * @param string $text
1066
     *
1067
     * @return array
1068
     */
1069
    public function saveUserMessage($subject, $text, array $receivers)
1070
    {
1071
        foreach ($receivers as $userId) {
1072
            MessageManager::send_message($userId, $subject, $text);
1073
        }
1074
1075
        return [
1076
            'sent' => true,
1077
        ];
1078
    }
1079
1080
    /**
1081
     * @param string $search
1082
     *
1083
     * @return array
1084
     */
1085
    public function getMessageUsers($search)
1086
    {
1087
        $repo = UserManager::getRepository();
1088
1089
        $users = $repo->findUsersToSendMessage($this->user->getId(), $search);
1090
        $showEmail = api_get_setting('show_email_addresses') === 'true';
1091
        $data = [];
1092
1093
        /** @var User $user */
1094
        foreach ($users as $user) {
1095
            $userName = UserManager::formatUserFullName($user);
1096
1097
            if ($showEmail) {
1098
                $userName .= " ({$user->getEmail()})";
1099
            }
1100
1101
            $data[] = [
1102
                'id' => $user->getId(),
1103
                'name' => $userName,
1104
            ];
1105
        }
1106
1107
        return $data;
1108
    }
1109
1110
    /**
1111
     * @param string $title
1112
     * @param string $text
1113
     *
1114
     * @return array
1115
     */
1116
    public function saveCourseNotebook($title, $text)
1117
    {
1118
        $values = ['note_title' => $title, 'note_comment' => $text];
1119
        $sessionId = $this->session ? $this->session->getId() : 0;
1120
1121
        $noteBookId = NotebookManager::save_note(
1122
            $values,
1123
            $this->user->getId(),
1124
            $this->course->getId(),
1125
            $sessionId
1126
        );
1127
1128
        return [
1129
            'registered' => $noteBookId,
1130
        ];
1131
    }
1132
1133
    /**
1134
     * @param int $forumId
1135
     *
1136
     * @return array
1137
     */
1138
    public function saveForumThread(array $values, $forumId)
1139
    {
1140
        require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1141
1142
        $sessionId = $this->session ? $this->session->getId() : 0;
1143
        $forum = get_forums($forumId, $this->course->getCode(), true, $sessionId);
1144
        $courseInfo = api_get_course_info($this->course->getCode());
1145
        $thread = store_thread($forum, $values, $courseInfo, false, $this->user->getId(), $sessionId);
1146
1147
        return [
1148
            'registered' => $thread->getIid(),
1149
        ];
1150
    }
1151
1152
    /**
1153
     * @return array
1154
     */
1155
    public function getUsersCampus(array $params)
1156
    {
1157
        $conditions = [
1158
            'status' => $params['status'],
1159
        ];
1160
        $idCampus = $params['id_campus'];
1161
        $users = UserManager::get_user_list($conditions, ['firstname'], false, false, $idCampus);
1162
        $list = [];
1163
        foreach ($users as $item) {
1164
            $listTemp = [
1165
                'id' => $item['user_id'],
1166
                'firstname' => $item['firstname'],
1167
                'lastname' => $item['lastname'],
1168
                'email' => $item['email'],
1169
            ];
1170
            $list[] = $listTemp;
1171
        }
1172
1173
        return $list;
1174
    }
1175
1176
    /**
1177
     * @return array
1178
     */
1179
    public function getCoursesCampus(array $params)
1180
    {
1181
        $idCampus = $params['id_campus'];
1182
1183
        $courseList = CourseManager::get_courses_list(
1184
            0, //offset
1185
            0, //howMany
1186
            1, //$orderby = 1
1187
            'ASC',
1188
            -1, //visibility
1189
            null,
1190
            $idCampus, //$urlId
1191
            true //AlsoSearchCode
1192
        );
1193
1194
        return $courseList;
1195
    }
1196
1197
    /**
1198
     * @return array
1199
     */
1200
    public function addSession(array $params)
1201
    {
1202
        $name = $params['name'];
1203
        $coach_username = (int) $params['coach_username'];
1204
        $startDate = $params['access_start_date'];
1205
        $endDate = $params['access_end_date'];
1206
        $displayStartDate = $startDate;
1207
        $displayEndDate = $endDate;
1208
        $description = $params['description'];
1209
        $idUrlCampus = $params['id_campus'];
1210
        $extraFields = isset($params['extra']) ? $params['extra'] : [];
1211
1212
        $return = SessionManager::create_session(
1213
            $name,
1214
            $startDate,
1215
            $endDate,
1216
            $displayStartDate,
1217
            $displayEndDate,
1218
            null,
1219
            null,
1220
            $coach_username,
1221
            null,
1222
            1,
1223
            false,
1224
            null,
1225
            $description,
1226
            1,
1227
            $extraFields,
1228
            null,
1229
            false,
1230
            $idUrlCampus
1231
        );
1232
1233
        if ($return) {
1234
            $out = [
1235
                'status' => true,
1236
                'message' => get_lang('ANewSessionWasCreated'),
1237
                'id_session' => $return,
1238
            ];
1239
        } else {
1240
            $out = [
1241
                'status' => false,
1242
                'message' => get_lang('ErrorOccurred'),
1243
            ];
1244
        }
1245
1246
        return $out;
1247
    }
1248
1249
    public function addCourse(array $courseParam): array
1250
    {
1251
        $idCampus = isset($courseParam['id_campus']) ? $courseParam['id_campus'] : 1;
1252
        $title = isset($courseParam['title']) ? $courseParam['title'] : '';
1253
        $wantedCode = isset($courseParam['wanted_code']) ? $courseParam['wanted_code'] : null;
1254
        $diskQuota = isset($courseParam['disk_quota']) ? $courseParam['disk_quota'] : '100';
1255
        $visibility = isset($courseParam['visibility']) ? (int) $courseParam['visibility'] : null;
1256
1257
        if (isset($courseParam['visibility'])) {
1258
            if ($courseParam['visibility'] &&
1259
                $courseParam['visibility'] >= 0 &&
1260
                $courseParam['visibility'] <= 3
1261
            ) {
1262
                $visibility = (int) $courseParam['visibility'];
1263
            }
1264
        }
1265
1266
        $params = [];
1267
        $params['title'] = $title;
1268
        $params['wanted_code'] = 'CAMPUS_'.$idCampus.'_'.$wantedCode;
1269
        $params['user_id'] = $this->user->getId();
1270
        $params['visibility'] = $visibility;
1271
        $params['disk_quota'] = $diskQuota;
1272
1273
        $courseInfo = CourseManager::create_course($params, $params['user_id'], $idCampus);
1274
1275
        $results = [];
1276
        if (!empty($courseInfo)) {
1277
            $results['status'] = true;
1278
            $results['code_course'] = $courseInfo['code'];
1279
            $results['title_course'] = $courseInfo['title'];
1280
            $results['message'] = sprintf(get_lang('CourseXAdded'), $courseInfo['code']);
1281
        } else {
1282
            $results['status'] = false;
1283
            $results['message'] = get_lang('CourseCreationFailed');
1284
        }
1285
1286
        return $results;
1287
    }
1288
1289
    /**
1290
     * @param $userParam
1291
     *
1292
     * @throws Exception
1293
     *
1294
     * @return array
1295
     */
1296
    public function addUser($userParam)
1297
    {
1298
        $firstName = $userParam['firstname'];
1299
        $lastName = $userParam['lastname'];
1300
        $status = $userParam['status'];
1301
        $email = $userParam['email'];
1302
        $loginName = $userParam['loginname'];
1303
        $password = $userParam['password'];
1304
1305
        $official_code = '';
1306
        $language = '';
1307
        $phone = '';
1308
        $picture_uri = '';
1309
        $auth_source = PLATFORM_AUTH_SOURCE;
1310
        $expiration_date = '';
1311
        $active = 1;
1312
        $hr_dept_id = 0;
1313
        $extra = null;
1314
1315
        $original_user_id_name = $userParam['original_user_id_name'];
1316
        $original_user_id_value = $userParam['original_user_id_value'];
1317
1318
        $extra_list = isset($userParam['extra']) ? $userParam['extra'] : [];
1319
        if (isset($userParam['language'])) {
1320
            $language = $userParam['language'];
1321
        }
1322
        if (isset($userParam['phone'])) {
1323
            $phone = $userParam['phone'];
1324
        }
1325
        if (isset($userParam['expiration_date'])) {
1326
            $expiration_date = $userParam['expiration_date'];
1327
        }
1328
1329
        // Default language.
1330
        if (empty($language)) {
1331
            $language = api_get_setting('platformLanguage');
1332
        }
1333
1334
        // First check wether the login already exists.
1335
        if (!UserManager::is_username_available($loginName)) {
1336
            throw new Exception(get_lang('UserNameNotAvailable'));
1337
        }
1338
1339
        $userId = UserManager::create_user(
1340
            $firstName,
1341
            $lastName,
1342
            $status,
1343
            $email,
1344
            $loginName,
1345
            $password,
1346
            $official_code,
1347
            $language,
1348
            $phone,
1349
            $picture_uri,
1350
            $auth_source,
1351
            $expiration_date,
1352
            $active,
1353
            $hr_dept_id
1354
        );
1355
1356
        if (empty($userId)) {
1357
            throw new Exception(get_lang('UserNotRegistered'));
1358
        }
1359
1360
        if (api_is_multiple_url_enabled()) {
1361
            if (api_get_current_access_url_id() != -1) {
1362
                UrlManager::add_user_to_url(
1363
                    $userId,
1364
                    api_get_current_access_url_id()
1365
                );
1366
            } else {
1367
                UrlManager::add_user_to_url($userId, 1);
1368
            }
1369
        } else {
1370
            // We add by default the access_url_user table with access_url_id = 1
1371
            UrlManager::add_user_to_url($userId, 1);
1372
        }
1373
1374
        // Save new field label into user_field table.
1375
        UserManager::create_extra_field(
1376
            $original_user_id_name,
1377
            1,
1378
            $original_user_id_name,
1379
            ''
1380
        );
1381
        // Save the external system's id into user_field_value table.
1382
        UserManager::update_extra_field_value(
1383
            $userId,
1384
            $original_user_id_name,
1385
            $original_user_id_value
1386
        );
1387
1388
        if (is_array($extra_list) && count($extra_list) > 0) {
1389
            foreach ($extra_list as $extra) {
1390
                $extra_field_name = $extra['field_name'];
1391
                $extra_field_value = $extra['field_value'];
1392
                // Save new field label into user_field table.
1393
                UserManager::create_extra_field(
1394
                    $extra_field_name,
1395
                    1,
1396
                    $extra_field_name,
1397
                    ''
1398
                );
1399
                // Save the external system's id into user_field_value table.
1400
                UserManager::update_extra_field_value(
1401
                    $userId,
1402
                    $extra_field_name,
1403
                    $extra_field_value
1404
                );
1405
            }
1406
        }
1407
1408
        return [$userId];
1409
    }
1410
1411
    /**
1412
     * Subscribe User to Course.
1413
     *
1414
     * @param array $params
1415
     *
1416
     * @return array
1417
     */
1418
    public function subscribeUserToCourse($params)
1419
    {
1420
        $course_id = $params['course_id'];
1421
        $course_code = $params['course_code'];
1422
        $user_id = $params['user_id'];
1423
        $status = $params['status'] ?? STUDENT;
1424
1425
        if (!$course_id && !$course_code) {
1426
            return [false];
1427
        }
1428
        if (!$course_code) {
1429
            $course_code = CourseManager::get_course_code_from_course_id($course_id);
1430
        }
1431
1432
        if (CourseManager::subscribeUser($user_id, $course_code, $status)) {
1433
            return [true];
1434
        }
1435
1436
        return [false];
1437
    }
1438
1439
    public function unSubscribeUserToCourse(array $params): array
1440
    {
1441
        $courseId = $params['course_id'];
1442
        $courseCode = $params['course_code'];
1443
        $userId = $params['user_id'];
1444
1445
        if (!$courseId && !$courseCode) {
1446
            return [false];
1447
        }
1448
1449
        if (!$courseCode) {
1450
            $courseCode = CourseManager::get_course_code_from_course_id($courseId);
1451
        }
1452
1453
        if (CourseManager::unsubscribe_user($userId, $courseCode)) {
1454
            return [true];
1455
        }
1456
1457
        return [false];
1458
    }
1459
1460
    public function deleteUserMessage($messageId, $messageType)
1461
    {
1462
        if ($messageType === 'sent') {
1463
            return MessageManager::delete_message_by_user_sender($this->user->getId(), $messageId);
1464
        } else {
1465
            return MessageManager::delete_message_by_user_receiver($this->user->getId(), $messageId);
1466
        }
1467
    }
1468
1469
    public function setMessageRead($messageId)
1470
    {
1471
        MessageManager::update_message($this->user->getId(), $messageId);
1472
    }
1473
1474
    /**
1475
     * Add Campus Virtual.
1476
     *
1477
     * @param array Params Campus
1478
     *
1479
     * @return array
1480
     */
1481
    public function createCampusURL($params)
1482
    {
1483
        $urlCampus = Security::remove_XSS($params['url']);
1484
        $description = Security::remove_XSS($params['description']);
1485
1486
        $active = isset($params['active']) ? intval($params['active']) : 0;
1487
        $num = UrlManager::url_exist($urlCampus);
1488
        if ($num == 0) {
1489
            // checking url
1490
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1491
                $idCampus = UrlManager::add($urlCampus, $description, $active, true);
1492
            } else {
1493
                //create
1494
                $idCampus = UrlManager::add($urlCampus.'/', $description, $active, true);
1495
            }
1496
1497
            return [
1498
                'status' => true,
1499
                'id_campus' => $idCampus,
1500
            ];
1501
        }
1502
1503
        return [
1504
            'status' => false,
1505
            'id_campus' => 0,
1506
        ];
1507
    }
1508
1509
    /**
1510
     * Edit Campus Virtual.
1511
     *
1512
     * @param array Params Campus
1513
     *
1514
     * @return array
1515
     */
1516
    public function editCampusURL($params)
1517
    {
1518
        $urlCampus = Security::remove_XSS($params['url']);
1519
        $description = Security::remove_XSS($params['description']);
1520
1521
        $active = isset($params['active']) ? intval($params['active']) : 0;
1522
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1523
1524
        if (!empty($url_id)) {
1525
            //we can't change the status of the url with id=1
1526
            if ($url_id == 1) {
1527
                $active = 1;
1528
            }
1529
            //checking url
1530
            if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') {
1531
                UrlManager::update($url_id, $urlCampus, $description, $active);
1532
            } else {
1533
                UrlManager::update($url_id, $urlCampus.'/', $description, $active);
1534
            }
1535
1536
            return [true];
1537
        }
1538
1539
        return [false];
1540
    }
1541
1542
    /**
1543
     * Delete Campus Virtual.
1544
     *
1545
     * @param array Params Campus
1546
     *
1547
     * @return array
1548
     */
1549
    public function deleteCampusURL($params)
1550
    {
1551
        $url_id = isset($params['id']) ? intval($params['id']) : 0;
1552
1553
        $result = UrlManager::delete($url_id);
1554
        if ($result) {
1555
            return [
1556
                'status' => true,
1557
                'message' => get_lang('URLDeleted'),
1558
            ];
1559
        } else {
1560
            return [
1561
                'status' => false,
1562
                'message' => get_lang('Error'),
1563
            ];
1564
        }
1565
    }
1566
1567
    /**
1568
     * @throws Exception
1569
     *
1570
     * @return array
1571
     */
1572
    public function addCoursesSession(array $params)
1573
    {
1574
        $sessionId = $params['id_session'];
1575
        $courseList = $params['list_courses'];
1576
        $importAssignments = isset($params['import_assignments']) ? 1 === (int) $params['import_assignments'] : false;
1577
1578
        $result = SessionManager::add_courses_to_session(
1579
            $sessionId,
1580
            $courseList,
1581
            true,
1582
            false,
1583
            false,
1584
            $importAssignments
1585
        );
1586
1587
        if ($result) {
1588
            return [
1589
                'status' => $result,
1590
                'message' => get_lang('Updated'),
1591
            ];
1592
        }
1593
1594
        return [
1595
            'status' => $result,
1596
            'message' => get_lang('ErrorOccurred'),
1597
        ];
1598
    }
1599
1600
    /**
1601
     * @return array
1602
     */
1603
    public function addUsersSession(array $params)
1604
    {
1605
        $sessionId = $params['id_session'];
1606
        $userList = $params['list_users'];
1607
1608
        if (!is_array($userList)) {
1609
            $userList = [];
1610
        }
1611
1612
        SessionManager::subscribeUsersToSession(
1613
            $sessionId,
1614
            $userList,
1615
            null,
1616
            false
1617
        );
1618
1619
        return [
1620
            'status' => true,
1621
            'message' => get_lang('UsersAdded'),
1622
        ];
1623
    }
1624
1625
    /**
1626
     * Creates a session from a model session.
1627
     *
1628
     * @param $modelSessionId
1629
     * @param $sessionName
1630
     * @param $startDate
1631
     * @param $endDate
1632
     *
1633
     * @throws Exception
1634
     *
1635
     * @return int, the id of the new session
1636
     */
1637
    public function createSessionFromModel($modelSessionId, $sessionName, $startDate, $endDate, array $extraFields = [])
1638
    {
1639
        if (empty($modelSessionId) || empty($sessionName) || empty($startDate) || empty($endDate)) {
1640
            throw new Exception(get_lang('NoData'));
1641
        }
1642
1643
        if (!SessionManager::isValidId($modelSessionId)) {
1644
            throw new Exception(get_lang('ModelSessionDoesNotExist'));
1645
        }
1646
1647
        $modelSession = SessionManager::fetch($modelSessionId);
1648
1649
        $modelSession['accessUrlId'] = 1;
1650
        if (api_is_multiple_url_enabled()) {
1651
            if (api_get_current_access_url_id() != -1) {
1652
                $modelSession['accessUrlId'] = api_get_current_access_url_id();
1653
            }
1654
        }
1655
1656
        $newSessionId = SessionManager::create_session(
1657
            $sessionName,
1658
            $startDate,
1659
            $endDate,
1660
            $startDate,
1661
            $endDate,
1662
            $startDate,
1663
            $endDate,
1664
            $modelSession['id_coach'],
1665
            $modelSession['session_category_id'],
1666
            $modelSession['visibility'],
1667
            false,
1668
            $modelSession['duration'],
1669
            $modelSession['description'],
1670
            $modelSession['show_description'],
1671
            $extraFields,
1672
            $modelSession['session_admin_id'],
1673
            $modelSession['send_subscription_notification'],
1674
            $modelSession['accessUrlId']
1675
        );
1676
1677
        if (empty($newSessionId)) {
1678
            throw new Exception(get_lang('SessionNotRegistered'));
1679
        }
1680
1681
        if (is_string($newSessionId)) {
1682
            throw new Exception($newSessionId);
1683
        }
1684
1685
        $promotionId = $modelSession['promotion_id'];
1686
        if ($promotionId) {
1687
            $sessionList = array_keys(SessionManager::get_all_sessions_by_promotion($promotionId));
1688
            $sessionList[] = $newSessionId;
1689
            SessionManager::subscribe_sessions_to_promotion($modelSession['promotion_id'], $sessionList);
1690
        }
1691
1692
        $modelExtraFields = [];
1693
        $fields = SessionManager::getFilteredExtraFields($modelSessionId);
1694
        if (is_array($fields) and !empty($fields)) {
1695
            foreach ($fields as $field) {
1696
                $modelExtraFields[$field['variable']] = $field['value'];
1697
            }
1698
        }
1699
        $allExtraFields = array_merge($modelExtraFields, $extraFields);
1700
        foreach ($allExtraFields as $name => $value) {
1701
            // SessionManager::update_session_extra_field_value returns false when no row is changed,
1702
            // which can happen since extra field values are initialized by SessionManager::create_session
1703
            // therefore we do not throw an exception when false is returned
1704
            SessionManager::update_session_extra_field_value($newSessionId, $name, $value);
1705
        }
1706
1707
        $courseList = array_keys(SessionManager::get_course_list_by_session_id($modelSessionId));
1708
        if (is_array($courseList)
1709
            && !empty($courseList)
1710
            && !SessionManager::add_courses_to_session($newSessionId, $courseList)) {
1711
            throw new Exception(get_lang('CoursesNotAddedToSession'));
1712
        }
1713
1714
        if (api_is_multiple_url_enabled()) {
1715
            if (api_get_current_access_url_id() != -1) {
1716
                UrlManager::add_session_to_url(
1717
                    $newSessionId,
1718
                    api_get_current_access_url_id()
1719
                );
1720
            } else {
1721
                UrlManager::add_session_to_url($newSessionId, 1);
1722
            }
1723
        } else {
1724
            UrlManager::add_session_to_url($newSessionId, 1);
1725
        }
1726
1727
        return $newSessionId;
1728
    }
1729
1730
    /**
1731
     * subscribes a user to a session.
1732
     *
1733
     * @param int    $sessionId the session id
1734
     * @param string $loginName the user's login name
1735
     *
1736
     * @throws Exception
1737
     *
1738
     * @return boolean, whether it worked
1739
     */
1740
    public function subscribeUserToSessionFromUsername($sessionId, $loginName)
1741
    {
1742
        if (!SessionManager::isValidId($sessionId)) {
1743
            throw new Exception(get_lang('SessionNotFound'));
1744
        }
1745
1746
        $userId = UserManager::get_user_id_from_username($loginName);
1747
        if (false === $userId) {
1748
            throw new Exception(get_lang('UserNotFound'));
1749
        }
1750
1751
        $subscribed = SessionManager::subscribeUsersToSession(
1752
            $sessionId,
1753
            [$userId],
1754
            SESSION_VISIBLE_READ_ONLY,
1755
            false
1756
        );
1757
        if (!$subscribed) {
1758
            throw new Exception(get_lang('UserNotSubscribed'));
1759
        }
1760
1761
        return true;
1762
    }
1763
1764
    /**
1765
     * finds the session which has a specific value in a specific extra field.
1766
     *
1767
     * @param $fieldName
1768
     * @param $fieldValue
1769
     *
1770
     * @throws Exception when no session matched or more than one session matched
1771
     *
1772
     * @return int, the matching session id
1773
     */
1774
    public function getSessionFromExtraField($fieldName, $fieldValue)
1775
    {
1776
        // find sessions that that have value in field
1777
        $valueModel = new ExtraFieldValue('session');
1778
        $sessionIdList = $valueModel->get_item_id_from_field_variable_and_field_value(
1779
            $fieldName,
1780
            $fieldValue,
1781
            false,
1782
            false,
1783
            true
1784
        );
1785
1786
        // throw if none found
1787
        if (empty($sessionIdList)) {
1788
            throw new Exception(get_lang('NoSessionMatched'));
1789
        }
1790
1791
        // throw if more than one found
1792
        if (count($sessionIdList) > 1) {
1793
            throw new Exception(get_lang('MoreThanOneSessionMatched'));
1794
        }
1795
1796
        // return sessionId
1797
        return intval($sessionIdList[0]['item_id']);
1798
    }
1799
1800
    /**
1801
     * updates a user identified by its login name.
1802
     *
1803
     * @param array $parameters
1804
     *
1805
     * @throws Exception on failure
1806
     *
1807
     * @return boolean, true on success
1808
     */
1809
    public function updateUserFromUserName($parameters)
1810
    {
1811
        // find user
1812
        $userId = null;
1813
        if (!is_array($parameters) || empty($parameters)) {
1814
            throw new Exception('NoData');
1815
        }
1816
        foreach ($parameters as $name => $value) {
1817
            if (strtolower($name) === 'loginname') {
1818
                $userId = UserManager::get_user_id_from_username($value);
1819
                if (false === $userId) {
1820
                    throw new Exception(get_lang('UserNotFound'));
1821
                }
1822
                break;
1823
            }
1824
        }
1825
        if (is_null($userId)) {
1826
            throw new Exception(get_lang('NoData'));
1827
        }
1828
        /** @var User $user */
1829
        $user = UserManager::getRepository()->find($userId);
1830
        if (empty($user)) {
1831
            throw new Exception(get_lang('CouldNotLoadUser'));
1832
        }
1833
1834
        // tell the world we are about to update a user
1835
        $hook = HookUpdateUser::create();
1836
        if (!empty($hook)) {
1837
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_PRE);
1838
        }
1839
1840
        // apply submitted modifications
1841
        foreach ($parameters as $name => $value) {
1842
            switch (strtolower($name)) {
1843
                case 'email':
1844
                    $user->setEmail($value);
1845
                    break;
1846
                case 'enabled':
1847
                    $user->setEnabled($value);
1848
                    break;
1849
                case 'lastname':
1850
                    $user->setLastname($value);
1851
                    break;
1852
                case 'firstname':
1853
                    $user->setFirstname($value);
1854
                    break;
1855
                case 'phone':
1856
                    $user->setPhone($value);
1857
                    break;
1858
                case 'address':
1859
                    $user->setAddress($value);
1860
                    break;
1861
                case 'roles':
1862
                    $user->setRoles($value);
1863
                    break;
1864
                case 'profile_completed':
1865
                    $user->setProfileCompleted($value);
1866
                    break;
1867
                case 'auth_source':
1868
                    $user->setAuthSource($value);
1869
                    break;
1870
                case 'status':
1871
                    $user->setStatus($value);
1872
                    break;
1873
                case 'official_code':
1874
                    $user->setOfficialCode($value);
1875
                    break;
1876
                case 'picture_uri':
1877
                    $user->setPictureUri($value);
1878
                    break;
1879
                case 'creator_id':
1880
                    $user->setCreatorId($value);
1881
                    break;
1882
                case 'competences':
1883
                    $user->setCompetences($value);
1884
                    break;
1885
                case 'diplomas':
1886
                    $user->setDiplomas($value);
1887
                    break;
1888
                case 'openarea':
1889
                    $user->setOpenArea($value);
1890
                    break;
1891
                case 'teach':
1892
                    $user->setTeach($value);
1893
                    break;
1894
                case 'productions':
1895
                    $user->setProductions($value);
1896
                    break;
1897
                case 'language':
1898
                    $languages = api_get_languages();
1899
                    if (!in_array($value, $languages['folder'])) {
1900
                        throw new Exception(get_lang('LanguageUnavailable'));
1901
                    }
1902
                    $user->setLanguage($value);
1903
                    break;
1904
                case 'registration_date':
1905
                    $user->setRegistrationDate($value);
1906
                    break;
1907
                case 'expiration_date':
1908
                    $user->setExpirationDate(
1909
                        new DateTime(
1910
                            api_get_utc_datetime($value),
1911
                            new DateTimeZone('UTC')
1912
                        )
1913
                    );
1914
                    break;
1915
                case 'active':
1916
                    // see UserManager::update_user() usermanager.lib.php:1205
1917
                    if ($user->getActive() != $value) {
1918
                        $user->setActive($value);
1919
                        Event::addEvent($value ? LOG_USER_ENABLE : LOG_USER_DISABLE, LOG_USER_ID, $userId);
1920
                    }
1921
                    break;
1922
                case 'openid':
1923
                    $user->setOpenId($value);
1924
                    break;
1925
                case 'theme':
1926
                    $user->setTheme($value);
1927
                    break;
1928
                case 'hr_dept_id':
1929
                    $user->setHrDeptId($value);
1930
                    break;
1931
                case 'extra':
1932
                    if (is_array($value)) {
1933
                        if (count($value) > 0) {
1934
                            if (is_array($value[0])) {
1935
                                foreach ($value as $field) {
1936
                                    $fieldName = $field['field_name'];
1937
                                    $fieldValue = $field['field_value'];
1938
                                    if (!isset($fieldName) || !isset($fieldValue) ||
1939
                                        !UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
1940
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.print_r($field, true));
1941
                                    }
1942
                                }
1943
                            } else {
1944
                                foreach ($value as $fieldName => $fieldValue) {
1945
                                    if (!UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) {
1946
                                        throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.$fieldName);
1947
                                    }
1948
                                }
1949
                            }
1950
                        }
1951
                    }
1952
                    break;
1953
                case 'username':
1954
                case 'api_key':
1955
                case 'action':
1956
                case 'loginname':
1957
                    break;
1958
                case 'email_canonical':
1959
                case 'locked':
1960
                case 'expired':
1961
                case 'credentials_expired':
1962
                case 'credentials_expire_at':
1963
                case 'expires_at':
1964
                case 'salt':
1965
                case 'last_login':
1966
                case 'created_at':
1967
                case 'updated_at':
1968
                case 'confirmation_token':
1969
                case 'password_requested_at':
1970
                case 'password': // see UserManager::update_user usermanager.lib.php:1182
1971
                case 'username_canonical':
1972
                default:
1973
                    throw new Exception(get_lang('UnsupportedUpdate')." '$name'");
1974
            }
1975
        }
1976
1977
        // save modifications
1978
        UserManager::getManager()->updateUser($user, true);
1979
1980
        // tell the world we just updated this user
1981
        if (!empty($hook)) {
1982
            $hook->setEventData(['user' => $user]);
1983
            $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST);
1984
        }
1985
1986
        // invalidate cache for this user
1987
        $cacheAvailable = api_get_configuration_value('apc');
1988
        if ($cacheAvailable === true) {
1989
            $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$userId;
1990
            if (apcu_exists($apcVar)) {
1991
                apcu_delete($apcVar);
1992
            }
1993
        }
1994
1995
        return true;
1996
    }
1997
1998
    /**
1999
     * Returns whether a user login name exists.
2000
     *
2001
     * @param string $loginname the user login name
2002
     *
2003
     * @return bool whether the user login name exists
2004
     */
2005
    public function usernameExist($loginname)
2006
    {
2007
        return false !== api_get_user_info_from_username($loginname);
2008
    }
2009
2010
    /**
2011
     * This service roughly matches what the call to MDL's API core_course_get_contents function returns.
2012
     *
2013
     * @return array
2014
     */
2015
    public function getCourseQuizMdlCompat()
2016
    {
2017
        $userId = $this->user->getId();
2018
        $courseId = $this->course->getId();
2019
        $sessionId = $this->session ? $this->session->getId() : 0;
2020
2021
        $toolVisibility = CourseHome::getToolVisibility(TOOL_QUIZ, $courseId, $sessionId);
2022
2023
        $json = [
2024
            "id" => $this->course->getId(),
2025
            "name" => get_lang('Exercises'),
2026
            "visible" => (int) $toolVisibility,
2027
            "summary" => '',
2028
            "summaryformat" => 1,
2029
            "section" => 1,
2030
            "hiddenbynumsections" => 0,
2031
            "uservisible" => $toolVisibility,
2032
            "modules" => [],
2033
        ];
2034
2035
        $quizIcon = Display::return_icon('quiz.png', '', [], ICON_SIZE_SMALL, false, true);
2036
2037
        $json['modules'] = array_map(
2038
            function (array $exercise) use ($quizIcon) {
2039
                return [
2040
                    'id' => $exercise['id'],
2041
                    'url' => $exercise['url'],
2042
                    'name' => $exercise['name'],
2043
                    'instance' => 1,
2044
                    'visible' => 1,
2045
                    'uservisible' => true,
2046
                    'visibleoncoursepage' => 0,
2047
                    'modicon' => $quizIcon,
2048
                    'modname' => 'quiz',
2049
                    'modplural' => get_lang('Exercises'),
2050
                    'availability' => null,
2051
                    'indent' => 0,
2052
                    'onclick' => '',
2053
                    'afterlink' => null,
2054
                    'customdata' => "",
2055
                    'noviewlink' => false,
2056
                    'completion' => (int) ($exercise[1] > 0),
2057
                ];
2058
            },
2059
            Exercise::exerciseGrid(0, '', $userId, $courseId, $sessionId, true)
2060
        );
2061
2062
        return [$json];
2063
    }
2064
2065
    /**
2066
     * @param array $additionalParams Optional
2067
     *
2068
     * @return string
2069
     */
2070
    private function encodeParams(array $additionalParams = [])
2071
    {
2072
        $params = array_merge(
2073
            $additionalParams,
2074
            [
2075
                'api_key' => $this->apiKey,
2076
                'username' => $this->user->getUsername(),
2077
            ]
2078
        );
2079
2080
        return json_encode($params);
2081
    }
2082
}
2083