PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.93
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.93
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / Modules / Course / Http / Controllers / CourseAdminController.php

CourseAdminController.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.93, at Modules/Course/Http/Controllers/CourseAdminController.php

917 lines 28.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Modules\Course\Http\Controllers;
4
5 use FluentCommunity\App\Http\Controllers\Controller;
6 use FluentCommunity\App\Models\BaseSpace;
7 use FluentCommunity\App\Models\Comment;
8 use FluentCommunity\App\Models\Feed;
9 use FluentCommunity\App\Models\Reaction;
10 use FluentCommunity\App\Models\SpaceGroup;
11 use FluentCommunity\App\Models\User;
12 use FluentCommunity\App\Models\XProfile;
13 use FluentCommunity\App\Services\CustomSanitizer;
14 use FluentCommunity\App\Services\Helper;
15 use FluentCommunity\App\Services\LockscreenService;
16 use FluentCommunity\App\Services\ProfileHelper;
17 use FluentCommunity\App\Services\FeedsHelper;
18 use FluentCommunity\Framework\Http\Request\Request;
19 use FluentCommunity\Framework\Support\Arr;
20 use FluentCommunity\App\Models\SpaceUserPivot;
21 use FluentCommunity\Modules\Course\Model\Course;
22 use FluentCommunity\Modules\Course\Model\CourseLesson;
23 use FluentCommunity\Modules\Course\Model\CourseTopic;
24 use FluentCommunity\Modules\Course\Services\CourseHelper;
25
26 class CourseAdminController extends Controller
27 {
28 public function getCourses(Request $request)
29 {
30 $courses = Course::byAdminAccess(get_current_user_id())
31 ->searchBy($request->get('search'))
32 ->orderBy('id', 'DESC')
33 ->with(['owner'])
34 ->paginate();
35
36 foreach ($courses as $course) {
37 $course->students_count = $course->students()->count();
38 if (!$course->cover_photo) {
39 $course->cover_photo = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/course-placeholder.jpg';
40 }
41 $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();
42 $course->lessonsCount = CourseLesson::where('space_id', $course->id)->count();
43 }
44
45 return [
46 'courses' => $courses
47 ];
48 }
49
50 public function createCourse(Request $request)
51 {
52 $this->validate($request->all(), [
53 'title' => 'required',
54 'description' => 'required',
55 'privacy' => 'required|in:public,private,secret',
56 'course_type' => 'required|in:self_paced,structured,scheduled',
57 'patent_id' => 'nullable|exists:fcom_spaces,id'
58 ]);
59
60 $parentId = $request->get('parent_id');
61
62 $courseData = [
63 'parent_id' => $request->get('parent_id'),
64 'title' => $request->getSafe('title', 'sanitize_text_field'),
65 'privacy' => $request->get('privacy'),
66 'description' => wp_kses_post($request->get('description')),
67 'status' => 'draft',
68 'settings' => [
69 'course_type' => $request->get('course_type'),
70 'emoji' => CustomSanitizer::sanitizeEmoji($request->get('settings.emoji', '')),
71 'shape_svg' => CustomSanitizer::sanitizeSvg($request->get('settings.shape_svg', '')),
72 ],
73 'serial' => BaseSpace::where('parent_id', $parentId)->max('serial') + 1
74 ];
75
76 $slug = $request->get('slug');
77
78 if (!$slug) {
79 $slug = sanitize_title($courseData['title']);
80 }
81
82 if ($slug) {
83 $slug = sanitize_title($slug);
84 // check if the slug is available for this type
85 $exist = Course::where('slug', $slug)
86 ->exists();
87
88 if ($exist) {
89 $slug = $slug . '-' . time();
90 }
91
92 $courseData['slug'] = $slug;
93 }
94
95 $course = Course::create($courseData);
96
97 $imageTypes = ['cover_photo', 'logo'];
98
99 $metaData = [];
100 foreach ($imageTypes as $type) {
101 if (!empty($request->get($type))) {
102 $media = Helper::getMediaFromUrl($request->get($type));
103 if (!$media || $media->is_active) {
104 continue;
105 }
106 $metaData[$type] = $media->public_url;
107 $media->update([
108 'is_active' => true,
109 'user_id' => get_current_user_id(),
110 'sub_object_id' => $course->id,
111 'object_source' => 'space_' . $type
112 ]);
113 }
114 }
115
116 if ($metaData) {
117 $course->fill($metaData);
118 $course->save();
119 }
120
121 return [
122 'course' => $course
123 ];
124 }
125
126 public function findCourse(Request $request, $courseId)
127 {
128 $course = Course::byAdminAccess(get_current_user_id())
129 ->where('id', $courseId)
130 ->with(['owner'])
131 ->first();
132
133 if (!$course) {
134 return $this->sendError([
135 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
136 ]);
137 }
138
139 $course->students_count = $course->students()->count();
140 $course->course_type = $course->settings['course_type'];
141 $course->lockscreen = $course->getLockscreen();
142
143 $course->category_ids = $course->categories->pluck('id')->toArray();
144
145 if ($course->students_count) {
146 $course->completed_students = $course->getCompletedStrundesCount();
147 $course->overAllProgress = CourseHelper::overallCourseProgressAverage($course);
148 }
149
150 unset($course->categories);
151
152 return [
153 'course' => $course
154 ];
155 }
156
157 public function updateCourse(Request $request, $courseId)
158 {
159 $this->validate($request->all(), [
160 'title' => 'required',
161 'description' => 'required',
162 'privacy' => 'required|in:public,private,secret',
163 'status' => 'required|in:draft,published,archived',
164 'course_type' => 'required|in:self_paced,structured,scheduled',
165 'parent_id' => 'required|exists:fcom_spaces,id'
166 ]);
167
168 $course = Course::byAdminAccess(get_current_user_id())
169 ->where('id', $courseId)
170 ->first();
171
172 if (!$course) {
173 return $this->sendError([
174 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
175 ]);
176 }
177
178 $courseData = [
179 'title' => $request->getSafe('title', 'sanitize_text_field'),
180 'privacy' => $request->get('privacy'),
181 'description' => wp_kses_post($request->get('description')),
182 'status' => $request->get('status'),
183 'cover_photo' => $request->getSafe('cover_photo', 'sanitize_url'),
184 'parent_id' => $request->get('parent_id'),
185 ];
186
187 $imageTypes = ['cover_photo', 'logo'];
188
189 foreach ($imageTypes as $type) {
190 if (!empty($request->get($type))) {
191 $media = Helper::getMediaFromUrl($request->get($type));
192 if (!$media || $media->is_active) {
193 continue;
194 }
195 $courseData[$type] = $media->public_url;
196 $media->update([
197 'is_active' => true,
198 'user_id' => get_current_user_id(),
199 'sub_object_id' => $course->id,
200 'object_source' => 'space_' . $type
201 ]);
202 }
203 }
204
205 $existingSettings = $course->settings;
206
207 $existingSettings['course_type'] = $request->get('course_type');
208 $existingSettings['custom_lock_screen'] = $request->get('settings.custom_lock_screen') === 'yes' ? 'yes' : 'no';
209 $existingSettings['emoji'] = CustomSanitizer::sanitizeEmoji($request->get('settings.emoji', ''));
210 $existingSettings['shape_svg'] = CustomSanitizer::sanitizeSvg($request->get('settings.shape_svg', ''));
211
212 $courseData['settings'] = $existingSettings;
213
214 $course->update($courseData);
215
216 $course->syncCategories($request->get('category_ids', []));
217
218 return [
219 'message' => __('Course has been updated successfully.', 'fluent-community'),
220 'course' => $course
221 ];
222 }
223
224 public function deleteCourse(Request $request, $courseId)
225 {
226 $course = Course::byAdminAccess(get_current_user_id())
227 ->where('id', $courseId)
228 ->first();
229
230 if (!$course || !Helper::isSiteAdmin()) {
231 return $this->sendError([
232 'message' => __('Course not found or you do not have permission to delete this course.', 'fluent-community')
233 ]);
234 }
235
236 // Let's remove the reactions
237 Reaction::query()->whereHas('feed', function ($q) use ($course) {
238 $q->where('space_id', $course->id);
239 })->delete();
240
241 Comment::whereHas('post', function ($q) use ($course) {
242 $q->where('space_id', $course->id);
243 })->delete();
244
245 Feed::withoutGlobalScopes()->where('space_id', $course->id)->delete();
246
247 // Let's delete the student enrollments
248 SpaceUserPivot::where('space_id', $course->id)
249 ->delete();
250
251 $courseId = $course->id;
252 $course->delete();
253
254 do_action('fluent_community/course/deleted', $courseId);
255
256 return [
257 'message' => __('Course has been deleted successfully along with all the associate data', 'fluent-community')
258 ];
259 }
260
261 public function getCourseComments(Request $request, $courseId)
262 {
263 $course = Course::byAdminAccess(get_current_user_id())
264 ->where('id', $courseId)
265 ->first();
266
267 if (!$course) {
268 return $this->sendError([
269 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
270 ]);
271 }
272
273 $comments = Comment::whereHas('post', function ($q) use ($courseId) {
274 return $q->where('space_id', $courseId);
275 })
276 ->orderBy('id', 'DESC')
277 ->with([
278 'post' => function ($q) {
279 return $q->select(['id', 'title', 'slug']);
280 },
281 'xprofile' => function ($q) {
282 $q->select(ProfileHelper::getXProfilePublicFields());
283 }
284 ])
285 ->paginate();
286
287 foreach ($comments as $comment) {
288 if ($comment->user) {
289 $comment->user->makeHidden(['user_email']);
290 }
291 $likedIds = FeedsHelper::getLikedIdsByUserFeedId($comment->post_id, get_current_user_id());
292 if ($likedIds && in_array($comment->id, $likedIds)) {
293 $comment->liked = 1;
294 }
295 }
296
297 return [
298 'comments' => $comments
299 ];
300 }
301
302 public function getCourseStudents(Request $request, $courseId)
303 {
304 $course = Course::byAdminAccess(get_current_user_id())
305 ->where('id', $courseId)
306 ->first();
307
308 if (!$course) {
309 return $this->sendError([
310 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
311 ]);
312 }
313
314 $search = $request->getSafe('search', 'sanitize_text_field');
315
316 $students = XProfile::whereHas('space_pivot', function ($q) use ($courseId) {
317 return $q->where('space_id', $courseId)
318 ->where('role', 'student');
319 })
320 ->searchBy($search)
321 ->with([
322 'space_pivot' => function ($q) use ($courseId) {
323 return $q->where('space_id', $courseId);
324 },
325 ])
326 ->select(ProfileHelper::getXProfilePublicFields())
327 ->paginate();
328
329 foreach ($students as $student) {
330 $student->progress = CourseHelper::getCourseProgress($courseId, $student->user_id);
331 }
332
333 return [
334 'students' => $students
335 ];
336 }
337
338 public function addStudent(Request $request, $courseId)
339 {
340 $course = Course::find($courseId);
341
342 if (!$course) {
343 return $this->sendError([
344 'message' => __('Course could not be found', 'fluent-community')
345 ]);
346 }
347
348 $this->validate($request->all(), [
349 'user_id' => 'required|exists:users,ID'
350 ]);
351
352 $userId = (int)$request->get('user_id');
353 $targetUser = User::findOrFail($userId);
354 $xprofile = $targetUser->syncXProfile();
355
356 if ($xprofile && $xprofile->status != 'active') {
357 return $this->sendError([
358 'message' => __('Selected user is not active', 'fluent-community')
359 ]);
360 }
361
362 $admin = User::find(get_current_user_id());
363 $admin->verifySpacePermission('can_add_member', $course);
364
365 $enrolled = CourseHelper::enrollCourse($course, $userId, 'by_admin');
366
367 if (!$enrolled) {
368 return $this->sendError([
369 'message' => __('User is already added in this course.', 'fluent-community')
370 ]);
371 }
372
373 do_action('fluent_community/course/joined', $course, $userId, 'by_admin');
374
375 return [
376 'message' => __('User has been added to this course', 'fluent-community')
377 ];
378 }
379
380 public function removeStudent(Request $request, $courseId, $studentId)
381 {
382 $course = Course::byAdminAccess(get_current_user_id())
383 ->where('id', $courseId)
384 ->first();
385
386 if (!$course) {
387 return $this->sendError([
388 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
389 ]);
390 }
391
392 $admin = User::find(get_current_user_id());
393
394 $admin->verifySpacePermission('can_remove_member', $course);
395
396 $student = SpaceUserPivot::bySpace($course->id)
397 ->byUser($studentId)
398 ->first();
399
400 if (!$student) {
401 return $this->sendError([
402 'message' => __('Selected user is not a student of this course', 'fluent-community')
403 ]);
404 }
405
406 $student->delete();
407
408 do_action('fluent_community/course/remove_student', $course, $studentId, 'by_admin');
409
410 return [
411 'message' => __('Student has been removed from this course', 'fluent-community')
412 ];
413 }
414
415 public function getSections(Request $request, $courseId)
416 {
417 $course = Course::byAdminAccess(get_current_user_id())
418 ->where('id', $courseId)
419 ->first();
420
421 if (!$course) {
422 return $this->sendError([
423 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
424 ]);
425 }
426
427 $sectionsQuery = CourseTopic::where('space_id', $courseId)
428 ->orderBy('priority', 'ASC');
429
430 if (in_array('only_published', $request->get('conditions', []))) {
431 $sectionsQuery->where('status', 'published')
432 ->with(['lessons' => function ($q) {
433 $q->where('status', 'published');
434 }]);
435 }
436
437 if (empty($request->get('conditions', []))) {
438 $sectionsQuery->with(['lessons']);
439 }
440
441 $sections = $sectionsQuery->get();
442
443 $data = [
444 'sections' => $sections
445 ];
446
447 if ($request->get('with_lock_screen')) {
448 $data['lockscreen'] = LockscreenService::getLockscreenSettings($course);
449 }
450
451 return $data;
452 }
453
454 public function getSection(Request $request, $courseId, $topicId)
455 {
456 $course = Course::byAdminAccess(get_current_user_id())
457 ->where('id', $courseId)
458 ->first();
459
460 if (!$course) {
461 return $this->sendError([
462 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
463 ]);
464 }
465
466 $topic = CourseTopic::where('space_id', $courseId)
467 ->where('id', $topicId)
468 ->with(['lessons'])
469 ->first();
470
471 if (!$topic) {
472 return $this->sendError([
473 'message' => __('Topic could not be found.', 'fluent-community')
474 ]);
475 }
476
477 return [
478 'topic' => $topic
479 ];
480 }
481
482 public function resetSectionIndexes(Request $request, $courseId)
483 {
484 $indexes = $request->get('indexes', []);
485
486 $sections = CourseTopic::where('space_id', $courseId)
487 ->whereIn('id', array_keys($indexes))
488 ->get();
489
490 foreach ($sections as $section) {
491 if (!isset($indexes[$section->id])) continue;
492 $section->priority = $indexes[$section->id];
493 $section->save();
494 }
495
496
497 return [
498 'sections' => $sections,
499 'message' => __('Sections indexes has been updated successfully.', 'fluent-community')
500 ];
501 }
502
503 public function resetLessonIndexes(Request $request, $courseId, $sectionId)
504 {
505 $indexes = $request->get('indexes', []);
506
507 $lessons = CourseLesson::where('space_id', $courseId)
508 ->where('parent_id', $sectionId)
509 ->whereIn('id', array_keys($indexes))
510 ->get();
511
512 foreach ($lessons as $lesson) {
513 if (!isset($indexes[$lesson->id])) continue;
514 $lesson->priority = $indexes[$lesson->id];
515 $lesson->save();
516 }
517
518 return [
519 'lessons' => $lessons,
520 'message' => __('Lessons indexes has been updated successfully.', 'fluent-community')
521 ];
522 }
523
524 public function createSection(Request $request, $courseId)
525 {
526 $this->validate($request->all(), [
527 'title' => 'required'
528 ]);
529
530 $course = Course::byAdminAccess(get_current_user_id())
531 ->where('id', $courseId)
532 ->first();
533
534 if (!$course) {
535 return $this->sendError([
536 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
537 ]);
538 }
539
540 $sectionData = [
541 'title' => $request->getSafe('title', 'sanitize_text_field'),
542 'space_id' => $courseId,
543 'status' => 'published'
544 ];
545
546 $section = CourseTopic::create($sectionData);
547
548 $section->load('lessons');
549
550 return [
551 'message' => __('Topic has been created successfully.', 'fluent-community'),
552 'section' => $section
553 ];
554 }
555
556 public function updateSection(Request $request, $courseId, $tipicId)
557 {
558 $this->validate($request->all(), [
559 'title' => 'required',
560 'status' => 'required|in:draft,published,archived'
561 ]);
562
563 $course = Course::byAdminAccess(get_current_user_id())
564 ->where('id', $courseId)
565 ->first();
566
567 $topic = CourseTopic::where('space_id', $courseId)
568 ->where('id', $tipicId)
569 ->first();
570
571 if (!$course && !$topic) {
572 return $this->sendError([
573 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
574 ]);
575 }
576
577
578 $topicData = [
579 'title' => $request->getSafe('title', 'sanitize_text_field'),
580 'status' => $request->get('status')
581 ];
582
583 $course->update($topicData);
584
585 return [
586 'message' => __('Topic has been updated successfully.', 'fluent-community'),
587 'topic' => $topic
588 ];
589 }
590
591 public function patchSection(Request $request, $courseId, $tipicId)
592 {
593 $course = Course::byAdminAccess(get_current_user_id())
594 ->where('id', $courseId)
595 ->first();
596
597 $topic = CourseTopic::where('space_id', $courseId)
598 ->where('id', $tipicId)
599 ->first();
600
601 if (!$course && !$topic) {
602 return $this->sendError([
603 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
604 ]);
605 }
606
607 $acceptedFields = ['title', 'status'];
608
609 if ($course->getCourseType() == 'scheduled') {
610 $acceptedFields[] = 'scheduled_at';
611 } else if ($course->getCourseType() == 'structured') {
612 $acceptedFields[] = 'reactions_count';
613 }
614
615
616 $topicData = $request->only($acceptedFields);
617
618 if (!empty($topicData['scheduled_at'])) {
619 $topic->reactions_count = 0;
620 } else if (isset($topicData['reactions_count'])) {
621 $topic->scheduled_at = null;
622 $topic->reactions_count = $topicData['reactions_count'];
623 }
624
625 $topicData = array_filter($topicData);
626 $topic->fill($topicData);
627 $topic->save();
628
629 return [
630 'message' => __('Topic has been updated successfully.', 'fluent-community'),
631 'topic' => $topic
632 ];
633 }
634
635 public function deleteSection(Request $request, $courseId, $sectionId)
636 {
637 $course = Course::byAdminAccess(get_current_user_id())
638 ->where('id', $courseId)
639 ->first();
640
641 $topic = CourseTopic::where('space_id', $courseId)
642 ->where('id', $sectionId)
643 ->first();
644
645 if (!$course && !$topic) {
646 return $this->sendError([
647 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
648 ]);
649 }
650
651 CourseTopic::where('id', $sectionId)
652 ->where('space_id', $courseId)
653 ->delete();
654
655 CourseLesson::where('parent_id', $sectionId)
656 ->where('space_id', $courseId)
657 ->delete();
658
659 return [
660 'message' => __('Section has been deleted successfully.', 'fluent-community')
661 ];
662 }
663
664 public function getLessons(Request $request, $courseId)
665 {
666 $course = Course::byAdminAccess(get_current_user_id())
667 ->where('id', $courseId)
668 ->first();
669
670 if (!$course) {
671 return $this->sendError([
672 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
673 ]);
674 }
675
676 $lessons = CourseLesson::where('space_id', $courseId)
677 ->orderBy('priority', 'ASC');
678
679 if ($request->get('topic_id')) {
680 $lessons = $lessons->where('parent_id', $request->get('topic_id'));
681 }
682
683 $lessons = $lessons->get();
684
685 return [
686 'lessons' => $lessons
687 ];
688 }
689
690 public function getLesson(Request $request, $courseId, $lessonId)
691 {
692 $course = Course::byAdminAccess(get_current_user_id())
693 ->where('id', $courseId)
694 ->first();
695
696 if (!$course) {
697 return $this->sendError([
698 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
699 ]);
700 }
701
702 $lesson = CourseLesson::where('space_id', $courseId)
703 ->where('id', $lessonId)
704 ->with(['topic', 'course'])
705 ->first();
706
707 if (!$lesson) {
708 return $this->sendError([
709 'message' => __('Lesson could not be found.', 'fluent-community')
710 ]);
711 }
712
713 return [
714 'lesson' => $lesson
715 ];
716 }
717
718 public function createLesson(Request $request, $courseId)
719 {
720 $this->validate($request->all(), [
721 'title' => 'required',
722 'section_id' => 'required'
723 ]);
724
725 $course = Course::byAdminAccess(get_current_user_id())
726 ->where('id', $courseId)
727 ->first();
728
729 $topic = CourseTopic::where('id', $request->get('section_id'))
730 ->where('space_id', $courseId)
731 ->first();
732
733 if (!$course || !$topic) {
734 return $this->sendError([
735 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
736 ]);
737 }
738
739 $lessonData = [
740 'title' => $request->getSafe('title', 'sanitize_text_field'),
741 'parent_id' => $topic->id,
742 'space_id' => $courseId,
743 'status' => 'draft'
744 ];
745
746 $lesson = CourseLesson::create($lessonData);
747
748 $lesson = CourseLesson::findOrFail($lesson->id);
749
750 return [
751 'message' => __('Lesson has been created successfully.', 'fluent-community'),
752 'lesson' => $lesson
753 ];
754 }
755
756 public function updateLesson(Request $request, $courseId, $lessionId)
757 {
758 $lessonData = $request->get('lesson');
759
760 $this->validate($lessonData, [
761 'title' => 'required',
762 'parent_id' => 'required',
763 'status' => 'required|in:draft,published,archived'
764 ]);
765
766 $course = Course::byAdminAccess(get_current_user_id())
767 ->where('id', $courseId)
768 ->first();
769
770 $topic = CourseTopic::where('id', $lessonData['parent_id'])
771 ->where('space_id', $courseId)
772 ->first();
773
774 $lesson = CourseLesson::where('id', $lessionId)
775 ->where('space_id', $courseId)
776 ->first();
777
778 if (!$course || !$topic || !$lesson) {
779 return $this->sendError([
780 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
781 ]);
782 }
783
784 $updateData = array_filter([
785 'title' => sanitize_text_field(Arr::get($lessonData, 'title')),
786 'message' => wp_kses_post(Arr::get($lessonData, 'message')),
787 'status' => Arr::get($lessonData, 'status'),
788 'meta' => CourseHelper::sanitizeLessonMeta(Arr::get($lessonData, 'meta', []))
789 ]);
790
791 $lesson->fill($updateData);
792 $lesson->save();
793
794 return [
795 'message' => __('Lesson has been updated successfully.', 'fluent-community'),
796 'lesson' => $lesson
797 ];
798 }
799
800 public function patchLesson(Request $request, $courseId, $lessionId)
801 {
802 $course = Course::byAdminAccess(get_current_user_id())
803 ->where('id', $courseId)
804 ->first();
805
806 $lesson = CourseLesson::where('id', $lessionId)
807 ->where('space_id', $courseId)
808 ->first();
809
810 if (!$course || !$lesson) {
811 return $this->sendError([
812 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
813 ]);
814 }
815
816 $acceptedFields = ['title', 'status'];
817
818 $lessonData = array_filter($request->only($acceptedFields));
819
820 $lesson->fill($lessonData);
821 $lesson->save();
822
823 return [
824 'message' => __('Lesson has been updated successfully.', 'fluent-community'),
825 'lesson' => $lesson
826 ];
827 }
828
829 public function deleteLesson(Request $request, $courseId, $lessionId)
830 {
831 $course = Course::byAdminAccess(get_current_user_id())
832 ->where('id', $courseId)
833 ->first();
834
835 $lesson = CourseLesson::where('id', $lessionId)
836 ->where('space_id', $courseId)
837 ->first();
838
839 if (!$lesson || !$course) {
840 return $this->sendError([
841 'message' => __('Lesson not found.', 'fluent-community')
842 ]);
843 }
844
845 $lesson->delete();
846
847 return [
848 'message' => __('Lesson has been deleted successfully.', 'fluent-community')
849 ];
850 }
851
852 public function updateLockscreenSettings(Request $request, $courseId)
853 {
854 $course = Course::byAdminAccess(get_current_user_id())
855 ->where('id', $courseId)
856 ->first();
857
858 if (!$course) {
859 return $this->sendError([
860 'message' => __('Course not found or you do not have access to this course.', 'fluent-community')
861 ]);
862 }
863
864 $settingFields = $request->get('lockscreen', []);
865
866 $formattedFields = LockscreenService::formatLockscreenFields($settingFields);
867
868 $course->setLockscreen($formattedFields);
869
870 return [
871 'message' => __('Lockscreen settings has been updated successfully.', 'fluent-community'),
872 'course' => $course
873 ];
874 }
875
876 public function getOtherUsers(Request $request)
877 {
878 $this->validate($request->all(), [
879 'course_id' => 'required|exists:fcom_spaces,id'
880 ]);
881
882 $courseId = (int)$request->get('course_id');
883
884 $search = sanitize_text_field($request->get('search'));
885
886 $users = User::whereDoesntHave('courses', function ($q) use ($courseId) {
887 $q->where('space_id', $courseId);
888 })
889 ->select(['ID', 'display_name'])
890 ->paginate();
891
892 return [
893 'users' => $users
894 ];
895 }
896
897 public function updateLinks(Request $request, $id)
898 {
899 $course = Course::findOrFail($id);
900 $links = $request->get('links', []);
901
902 $links = array_map(function ($link) {
903 return CustomSanitizer::santizeLinkItem($link);
904 }, $links);
905
906 $settings = $course->settings;
907 $settings['links'] = $links;
908 $course->settings = $settings;
909 $course->save();
910
911 return [
912 'message' => __('Links has been updated for the course', 'fluent-community'),
913 'links' => $links
914 ];
915 }
916 }
917