Passed
Push — master ( 176ab2...ab07af )
by Julito
11:00
created

Rest::encodeParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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