Passed
Push — 1.11.x ( 0d42cb...a203ca )
by Julito
12:11
created

Rest   F

Complexity

Total Complexity 266

Size/Duplication

Total Lines 2092
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1128
dl 0
loc 2092
rs 1.0879
c 1
b 0
f 0
wmc 266

53 Methods

Rating   Name   Duplication   Size   Complexity  
A getCourseAgenda() 0 49 4
A getCoursesCampus() 0 13 1
A addCoursesSession() 0 25 3
A getUserReceivedMessages() 0 31 3
A setCourse() 0 17 3
A getUsersCampus() 0 19 2
A deleteUserMessage() 0 6 2
A setMessageRead() 0 3 1
A showLearningPath() 0 25 2
A getUsersSubscribedToCourse() 0 16 2
A getUserSentMessages() 0 27 2
D addUser() 0 111 13
A decodeParams() 0 3 1
A getUserProfile() 0 28 2
A getUserCourses() 0 28 4
A usernameExist() 0 3 1
A getCourseForum() 0 34 5
A saveForumThread() 0 11 2
A encodeParams() 0 11 1
A getCourseNotebooks() 0 22 1
C getCourseLearnPaths() 0 108 17
A init() 0 11 2
A getMessageUsers() 0 23 3
A getSessionFromExtraField() 0 24 3
A setSession() 0 17 3
D createSessionFromModel() 0 91 20
A getCourseQuizMdlCompat() 0 48 2
A saveCourseNotebook() 0 14 2
A saveUserMessage() 0 8 2
A subscribeUserToSessionFromUsername() 0 22 4
A getUserMessages() 0 26 2
A getCourseAnnouncement() 0 26 3
A getCourseForumThread() 0 30 3
A getCourseInfo() 0 21 2
A saveForumPost() 0 9 1
A validate() 0 9 2
A __construct() 0 3 1
A addSession() 0 47 3
A getCourseDescriptions() 0 15 2
A getCourseLpProgress() 0 11 2
A setGcmId() 0 10 1
A getUserSessions() 0 48 5
A addUsersSession() 0 19 2
A createCampusURL() 0 25 4
F addCourse() 0 50 14
B getCourseForumCategories() 0 64 8
F updateUserFromUserName() 0 187 69
A unSubscribeUserToCourse() 0 19 5
A editCampusURL() 0 24 6
B getCourseDocuments() 0 71 8
A deleteCampusURL() 0 14 3
A getCourseAnnouncements() 0 32 2
A subscribeUserToCourse() 0 19 5

How to fix   Complexity   

Complex Class

Complex classes like Rest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Rest, and based on these observations, apply Extract Interface, too.

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