PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.95
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.95
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.95, at Modules/Course/Http/Controllers/CourseAdminController.php

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