PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.01
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.01
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
← All changes | Modules/Course/Http/Controllers/CourseController.php +394 -81 1.0.932.10.01 View file →
@@ -3,15 +3,18 @@
3 3 namespace FluentCommunity\Modules\Course\Http\Controllers;
4 4
5 5 use FluentCommunity\App\Http\Controllers\Controller;
6 6 use FluentCommunity\App\Models\SpaceUserPivot;
7 -use FluentCommunity\App\Models\User;
7 +use FluentCommunity\App\Services\Helper;
8 8 use FluentCommunity\App\Services\LockscreenService;
9 9 use FluentCommunity\Framework\Http\Request\Request;
10 +use FluentCommunity\Framework\Support\Arr;
10 11 use FluentCommunity\Modules\Course\Model\Course;
11 12 use FluentCommunity\Modules\Course\Model\CourseLesson;
12 13 use FluentCommunity\Modules\Course\Model\CourseTopic;
14 +use FluentCommunity\App\Services\FeedsHelper;
13 15 use FluentCommunity\Modules\Course\Services\CourseHelper;
16 +use FluentCommunity\Modules\Course\Services\LessonVideoGateService;
14 17
15 18 class CourseController extends Controller
16 19 {
17 20 public function getCourses(Request $request)
@@ -16,34 +19,44 @@
16 19 {
17 20 public function getCourses(Request $request)
18 21 {
19 22 $user = $this->getUser();
20 - $isModerator = $user && $user->isCommunityModerator();
23 + $isCourseCreator = $user && $user->hasCourseCreatorAccess();
24 + $enrolledIds = CourseHelper::getEnrolledCourseIds();
21 25
22 - if ($request->get('type') == 'enrolled') {
23 - $courses = Course::searchBy($request->get('search'))
24 - ->where('status', 'published')
25 - ->orderBy('title', 'ASC')
26 - ->byPostTopic($request->get('topic_slug'))
27 - ->whereIn('id', CourseHelper::getEnrolledCourseIds())
28 - ->paginate();
29 - } else {
30 - $courses = Course::searchBy($request->get('search'))
31 - ->when(!$isModerator, function ($q) {
26 + $search = $request->getSafe('search');
27 + $topicSlug = $request->getSafe('topic_slug');
28 + $isEnrolled = $request->getSafe('type') == 'enrolled';
29 + $sortBy = $request->getSafe('sort_by', 'sanitize_text_field', 'alphabetical');
30 +
31 + $courses = Course::searchBy($search)
32 + ->where(function ($q) use ($isCourseCreator, $isEnrolled, $user) {
33 + if ($isCourseCreator && !$isEnrolled) {
34 + $q->where('status', 'published')
35 + ->orWhere('created_by', $user->ID);
36 + } else {
32 37 $q->where('status', 'published');
33 - })
34 - ->byPostTopic($request->get('topic_slug'))
35 - ->orderBy('title', 'ASC')
36 - ->where(function ($q) {
37 - $q->whereIn('privacy', ['public', 'private']);
38 - if ($enrolledIds = CourseHelper::getEnrolledCourseIds()) {
39 - $q->orWhereIn('id', $enrolledIds);
40 - }
41 - })
42 - ->paginate();
43 - }
38 + }
39 + })
40 + ->byPostTopic($topicSlug)
41 + ->where(function ($q) use ($enrolledIds) {
42 + $q->whereIn('privacy', ['public', 'private']);
43 + $q->orWhereIn('id', $enrolledIds);
44 + })
45 + ->when($isEnrolled, function ($q) use ($enrolledIds) {
46 + $q->whereIn('id', $enrolledIds);
47 + })
48 + ->when($sortBy == 'alphabetical', function ($q) {
49 + $q->orderBy('title', 'ASC');
50 + })
51 + ->when($sortBy == 'oldest', function ($q) {
52 + $q->orderBy('created_at', 'ASC');
53 + })
54 + ->when($sortBy == 'latest', function ($q) {
55 + $q->orderBy('created_at', 'DESC');
56 + })
57 + ->paginate();
44 58
45 -
46 59 foreach ($courses as $course) {
47 60 $course->isEnrolled = CourseHelper::isEnrolled($course->id);
48 61 if ($course->isEnrolled) {
49 62 $course->progress = CourseHelper::getCourseProgress($course->id);
@@ -54,59 +67,168 @@
54 67 }
55 68
56 69 $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();
57 70 $course->lessonsCount = CourseLesson::where('space_id', $course->id)->count();
58 - $course->studentsCount = SpaceUserPivot::where('space_id', $course->id)->count();
71 + if (Arr::get($course->settings, 'hide_members_count') != 'yes') {
72 + $course->studentsCount = SpaceUserPivot::where('space_id', $course->id)->count();
73 + } else {
74 + $course->studentsCount = 0;
75 + }
76 +
77 + do_action_ref_array('fluent_community/course', [&$course]);
59 78 }
60 79
61 - return [
80 + $data = [
62 81 'courses' => $courses,
63 - 'course_categories' => $request->get('with_categories') ? CourseHelper::getCourseCategories() : []
82 + 'course_categories' => $request->get('with_categories') ? CourseHelper::getCourseCategories() : []
64 83 ];
84 +
85 + return apply_filters('fluent_community/courses_api_response', $data, $request->all());
65 86 }
66 87
67 88 public function getCourse(Request $request, $courseId)
68 89 {
69 90 $user = $this->getUser();
70 - $isModerator = $user && $user->isCommunityModerator();
71 91
72 - $course = Course::when(!$isModerator, function ($q) {
73 - $q->where('status', 'published');
74 - })->find($courseId);
92 + $course = Course::findOrFail($courseId);
93 + /** @var Course $course */
75 94
76 - if (!$course) {
95 + $isCourseCreator = $course->isCourseAdmin($user);
96 +
97 + if ($course->status !== 'published' && !$isCourseCreator) {
77 98 return $this->sendError([
78 - 'message' => 'Course not found. maybe the course is not published yet!'
99 + 'message' => __('Course not found. maybe the course is not published yet!', 'fluent-community')
79 100 ]);
80 101 }
81 102
82 - return $this->processCourse($course, $isModerator);
103 + $intendtedLessonSlug = $request->get('intended_lesson_slug');
104 +
105 + $data = $this->processCourse($course, $isCourseCreator, $intendtedLessonSlug);
106 +
107 + return apply_filters('fluent_community/get_course_api_response', $data, $request->all());
83 108 }
84 109
85 110 public function getCourseBySlug(Request $request, $slug)
86 111 {
87 112 $user = $this->getUser();
88 - $isModerator = $user && $user->isCommunityModerator();
89 113
90 - $course = Course::when(!$isModerator, function ($q) {
91 - $q->where('status', 'published');
92 - })->where('slug', $slug)->firstOrFail();
114 + $course = Course::where('slug', $slug)->firstOrFail();
115 + /** @var Course $course */
93 116
94 - if (!$course) {
117 + $isCourseCreator = $course->isCourseAdmin($user);
118 +
119 + if ($course->status !== 'published' && !$isCourseCreator) {
95 120 return $this->sendError([
96 - 'message' => 'Course not found. maybe the course is not published yet!'
121 + 'message' => __('Course not found. maybe the course is not published yet!', 'fluent-community')
97 122 ]);
98 123 }
99 124
100 - return $this->processCourse($course, $isModerator);
125 + $hideInstructorView = Arr::get($course->settings, 'hide_instructor_view') == 'yes';
126 + $showStudentCount = Arr::get($course->settings, 'show_instructor_students_count') == 'yes';
127 + if (!$hideInstructorView) {
128 + $course->load(['creator']);
129 + if ($course->creator) {
130 + $creatorCourseIds = Course::where('created_by', $course->creator->user_id)->pluck('id');
131 + $course->creator->total_courses = count($creatorCourseIds);
132 + if ($showStudentCount) {
133 + $course->creator->total_students = SpaceUserPivot::whereIn('space_id', $creatorCourseIds)->distinct('user_id')->count('user_id');
134 + }
135 + if ($course->creator->short_description) {
136 + $course->creator->short_description_rendered = wp_kses_post(FeedsHelper::mdToHtml($course->creator->short_description));
137 + }
138 + }
139 + }
140 +
141 + $intendtedLessonSlug = $request->get('intended_lesson_slug');
142 +
143 + $data = $this->processCourse($course, $isCourseCreator, $intendtedLessonSlug);
144 +
145 + return apply_filters('fluent_community/course_api_response', $data, $request->all());
101 146 }
102 147
103 - private function processCourse($course, $isModerator)
148 + public function getLessonBySlug(Request $request, $courseSlug, $lessonSlug)
104 149 {
150 + $user = $this->getUser();
151 +
152 + /** @var Course $course */
153 + $course = Course::where('slug', $courseSlug)->firstOrFail();
154 +
155 + $isCourseCreator = $course->isCourseAdmin($user);
156 +
157 + if ($course->status !== 'published' && !$isCourseCreator) {
158 + return $this->sendError([
159 + 'message' => __('Course not found. maybe the course is not published yet!', 'fluent-community')
160 + ]);
161 + }
162 +
163 + $lesson = CourseLesson::where('space_id', $course->id)
164 + ->where('slug', $lessonSlug)
165 + ->when(!$isCourseCreator, function ($q) {
166 + $q->where('status', 'published');
167 + })
168 + ->with(['topic'])
169 + ->firstOrFail();
170 +
171 + if (!$lesson || !$lesson->topic) {
172 + return $this->sendError([
173 + 'message' => __('Lesson not found. maybe the lesson is not published yet!', 'fluent-community')
174 + ]);
175 + }
176 +
177 + $enrollment = CourseHelper::getCourseEnrollment($course->id);
178 +
179 + if ($course->privacy == 'secret' && !$enrollment && !$isCourseCreator) {
180 + return $this->sendError([
181 + 'message' => __('You must need to be invited to view this course', 'fluent-community')
182 + ]);
183 + }
184 +
185 + $section = $lesson->topic;
186 + $hasAcessSectionAcess = !!$enrollment;
187 + $unlockDate = '';
188 + $courseType = $course->getCourseType();
189 + $hasPublicViewAccess = $course->privacy == 'public' && Arr::get($course->settings, 'public_lesson_view') == 'yes' && $courseType == 'self_paced';
190 + if ($hasAcessSectionAcess) {
191 + $unlockDate = CourseHelper::getSectionAccessDate($section, $courseType, $enrollment);
192 + if ($unlockDate && strtotime($unlockDate) > current_time('timestamp')) {
193 + $hasAcessSectionAcess = false;
194 + } else {
195 + $unlockDate = null;
196 + }
197 + }
198 +
199 + $initialCanView = $hasAcessSectionAcess || $isCourseCreator || $hasPublicViewAccess;
200 + $accessInfo = CourseHelper::resolveLessonAccess($initialCanView, $lesson, $course, $this->getUser(), [
201 + 'enrollment' => $enrollment,
202 + 'is_admin' => $isCourseCreator,
203 + 'has_section_access' => $hasAcessSectionAcess,
204 + 'has_public_access' => $hasPublicViewAccess,
205 + ]);
206 + $canViewLesson = $accessInfo['can_view'];
207 + $lockType = $accessInfo['lock_type'];
208 +
209 + $formattedLesson = CourseHelper::formatLessonData($course, $lesson, $user, [
210 + 'can_view' => $canViewLesson,
211 + 'parse_content' => $canViewLesson,
212 + 'is_locked' => !$canViewLesson && !$isCourseCreator,
213 + 'unlock_date' => $unlockDate,
214 + 'lock_type' => $lockType
215 + ]);
216 +
217 + $data = [
218 + 'lesson' => $formattedLesson
219 + ];
220 +
221 + return apply_filters('fluent_community/course_lesson_api_response', $data, $request->all());
222 + }
223 +
224 + private function processCourse(Course $course, $isCourseCreator, $intendtedLessonSlug = '')
225 + {
105 226 $sections = CourseTopic::where('space_id', $course->id)
106 227 ->orderBy('priority', 'ASC')
107 - ->with(['lessons' => function ($query) use ($isModerator) {
108 - if (!$isModerator) {
228 + ->orderBy('id', 'ASC')
229 + ->with(['lessons' => function ($query) use ($isCourseCreator) {
230 + if (!$isCourseCreator) {
109 231 $query->where('status', 'published');
110 232 }
111 233 }])
112 234 ->get();
@@ -111,22 +233,40 @@
111 233 }])
112 234 ->get();
113 235
114 236 $enrollment = CourseHelper::getCourseEnrollment($course->id);
115 - $formattedSections = [];
116 237
238 + $currentUser = Helper::getCurrentUser();
239 +
117 240 if ($course->privacy == 'private' && !$enrollment) {
118 - $course->lockscreen_config = LockscreenService::getLockscreenConfig($course);
241 + $course->lockscreen_config = LockscreenService::getLockscreenConfig($course, null, true);
119 242 }
120 243
121 - if ($course->privacy == 'secret' && !$enrollment && !$isModerator) {
244 + if ($course->privacy == 'secret' && !$enrollment && !$isCourseCreator) {
122 245 return $this->sendError([
123 - 'message' => 'You must need to be invited to view this course'
246 + 'message' => __('You must need to be invited to view this course', 'fluent-community')
124 247 ]);
125 248 }
126 249
250 + $course->is_course_admin = $isCourseCreator;
251 + $course->can_self_enroll = $isCourseCreator || ($course->status === 'published' && $course->privacy === 'public');
252 +
253 + $course = apply_filters('fluent_community/course/processed', $course, [
254 + 'is_enrolled' => !!$enrollment,
255 + ]);
256 +
257 + $courseSettings = $course->settings;
258 + if (Arr::get($courseSettings, 'course_details')) {
259 + $courseSettings['course_details_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($courseSettings['course_details']));
260 + $course->settings = $courseSettings;
261 + }
262 +
127 263 $courseType = $course->getCourseType();
128 264
265 + $hasPublicViewAccess = $course->privacy == 'public' && Arr::get($course->settings, 'public_lesson_view') == 'yes' && $courseType == 'self_paced';
266 +
267 + $formattedSections = [];
268 +
129 269 foreach ($sections as $section) {
130 270 if ($section->lessons->isEmpty()) {
131 271 continue;
132 272 }
@@ -135,9 +275,9 @@
135 275 $unlockDate = '';
136 276
137 277 if ($hasAcessSectionAcess) {
138 278 $unlockDate = CourseHelper::getSectionAccessDate($section, $courseType, $enrollment);
139 - if (!$unlockDate || strtotime($unlockDate) > current_time('timestamp')) {
279 + if ($unlockDate && strtotime($unlockDate) > current_time('timestamp')) {
140 280 $hasAcessSectionAcess = false;
141 281 } else {
142 282 $unlockDate = null;
143 283 }
@@ -142,32 +282,40 @@
142 282 $unlockDate = null;
143 283 }
144 284 }
145 285
286 + $sectionCtx = [
287 + 'enrollment' => $enrollment,
288 + 'is_admin' => $isCourseCreator,
289 + 'has_section_access' => $hasAcessSectionAcess,
290 + 'has_public_access' => $hasPublicViewAccess,
291 + ];
292 +
146 293 $formattedLessons = [];
147 294 foreach ($section->lessons as $lesson) {
148 - if ($hasAcessSectionAcess || $isModerator) {
149 - $content = $lesson->message_rendered;
150 - if (!$content && $lesson->message) {
151 - $content = apply_filters('widget_block_content', do_blocks($lesson->message));
152 - }
153 - } else {
154 - $content = '';
295 + $initialCanView = $hasAcessSectionAcess || $isCourseCreator || $hasPublicViewAccess;
296 + $accessInfo = CourseHelper::resolveLessonAccess($initialCanView, $lesson, $course, $this->getUser(), $sectionCtx);
297 + $canViewLesson = $accessInfo['can_view'];
298 + $lockType = $accessInfo['lock_type'];
299 +
300 + $parseContent = $intendtedLessonSlug === $lesson->slug && $canViewLesson;
301 +
302 + $formattedLesson = CourseHelper::formatLessonData($course, $lesson, $currentUser, [
303 + 'can_view' => $canViewLesson,
304 + 'parse_content' => $parseContent,
305 + 'is_locked' => !$canViewLesson && !$isCourseCreator,
306 + 'unlock_date' => $unlockDate,
307 + 'lock_type' => $lockType
308 + ]);
309 +
310 + $isLazyLoad = !$parseContent;
311 + if(!$canViewLesson && $lockType !== 'sequential') {
312 + $isLazyLoad = false;
155 313 }
156 314
157 - $formattedLessons[] = [
158 - 'id' => $lesson->id,
159 - 'title' => $lesson->title,
160 - 'content' => $content,
161 - 'slug' => $lesson->slug,
162 - 'course_id' => $lesson->space_id,
163 - 'section_id' => $lesson->parent_id,
164 - 'created_at' => $lesson->created_at,
165 - 'meta' => $lesson->meta,
166 - 'comments_count' => $lesson->comments_count,
167 - 'is_locked' => !$hasAcessSectionAcess && !$isModerator,
168 - 'unclock_date' => $unlockDate
169 - ];
315 + $formattedLesson['lazy_load'] = $isLazyLoad;
316 +
317 + $formattedLessons[] = $formattedLesson;
170 318 }
171 319
172 320 $formattedSections[] = [
173 321 'id' => $section->id,
@@ -175,9 +323,9 @@
175 323 'lessons' => $formattedLessons,
176 324 'created_at' => $section->created_at,
177 325 'slug' => $section->slug,
178 326 'type' => 'section',
179 - 'is_locked' => !$hasAcessSectionAcess && !$isModerator,
327 + 'is_locked' => !$hasAcessSectionAcess && !$isCourseCreator,
180 328 'unlock_date' => $unlockDate
181 329 ];
182 330 }
183 331
@@ -197,16 +345,21 @@
197 345 'message' => __('You need to login to enroll in this course.', 'fluent-community')
198 346 ]);
199 347 }
200 348
201 - $isModerator = $user->isCommunityModerator();
202 - $course = Course::when(!$isModerator, function ($q) {
203 - $q->where('status', 'published');
204 - })->findOrFail($courseId);
349 + $course = Course::findOrFail($courseId);
350 + /** @var Course $course */
205 351
352 + $isCourseCreator = $course->isCourseAdmin($user);
206 353
207 - if (!$isModerator && $course->privacy != 'public') {
354 + if ($course->status !== 'published' && !$isCourseCreator) {
208 355 return $this->sendError([
356 + 'message' => __('Course not found. maybe the course is not published yet!', 'fluent-community')
357 + ]);
358 + }
359 +
360 + if (!$isCourseCreator && $course->privacy != 'public') {
361 + return $this->sendError([
209 362 'message' => __('You are not allowed to enroll in this course.', 'fluent-community')
210 363 ]);
211 364 }
212 365
@@ -230,9 +383,9 @@
230 383 $course = Course::findOrFail($courseId);
231 384
232 385 if ($course->status != 'published') {
233 386 return $this->sendError([
234 - 'message' => __('Course is not on published state.', 'fluent-community')
387 + 'message' => __('Course is not in published state.', 'fluent-community')
235 388 ]);
236 389 }
237 390
238 391
@@ -237,9 +390,9 @@
237 390
238 391
239 392 if (!CourseHelper::isEnrolled($courseId)) {
240 393 return $this->sendError([
241 - 'message' => 'You are not enrolled in this action.'
394 + 'message' => __('Please enroll this course first', 'fluent-community')
242 395 ]);
243 396 }
244 397
245 398 $lesson = CourseLesson::where('space_id', $courseId)
@@ -248,9 +401,9 @@
248 401 ->first();
249 402
250 403 if (!$lesson) {
251 404 return $this->sendError([
252 - 'message' => 'Lesson is not on published state.'
405 + 'message' => __('Lesson is not on published state.', 'fluent-community')
253 406 ]);
254 407 }
255 408
256 409 $state = $request->get('state');
@@ -256,23 +409,183 @@
256 409 $state = $request->get('state');
257 410
258 411 if (!in_array($state, ['completed', 'incomplete'])) {
259 412 return $this->sendError([
260 - 'message' => 'Invalid state.'
413 + 'message' => __('Invalid state.', 'fluent-community')
261 414 ]);
262 415 }
263 416
417 + $isAllowed = apply_filters('fluent_community/is_allowed_to_complete_lesson', true, $lesson, $state);
418 +
419 + if (!$isAllowed) {
420 + $errorData = [
421 + 'message' => __('You are not allowed to complete this lesson.', 'fluent-community')
422 + ];
423 +
424 + if (LessonVideoGateService::isCompletionBlockedFor($lesson, Helper::getCurrentUser())) {
425 + $errorData['code'] = 'video_watch_required';
426 + $errorData['threshold'] = LessonVideoGateService::getThreshold($lesson);
427 + }
428 +
429 + return $this->sendError($errorData);
430 + }
431 +
264 432 CourseHelper::updateLessonCompletion($lesson, get_current_user_id(), $state);
265 433 $track = CourseHelper::getCourseProgressTrack($courseId);
266 434 $isCompleted = $track['progress'] == 100;
267 435
268 436 if ($isCompleted) {
269 - CourseHelper::completeCourse($course, get_current_user_id());
437 + CourseHelper::completeCourse($course, $lesson, get_current_user_id());
270 438 }
271 439
272 440 return [
273 - 'message' => 'Lesson completion state updated.',
441 + 'message' => __('Lesson completion state updated.', 'fluent-community'),
274 442 'track' => $track,
275 443 'is_completed' => $isCompleted
276 444 ];
445 + }
446 +
447 + public function markLessonVideoWatched(Request $request, $courseId, $lessonId)
448 + {
449 + $course = Course::findOrFail($courseId);
450 +
451 + if ($course->status != 'published') {
452 + return $this->sendError([
453 + 'message' => __('Course is not in published state.', 'fluent-community')
454 + ]);
455 + }
456 +
457 + if (!CourseHelper::isEnrolled($courseId)) {
458 + return $this->sendError([
459 + 'message' => __('Please enroll this course first', 'fluent-community')
460 + ]);
461 + }
462 +
463 + $lesson = CourseLesson::where('space_id', $courseId)
464 + ->where('status', 'published')
465 + ->where('id', $lessonId)
466 + ->first();
467 +
468 + if (!$lesson) {
469 + return $this->sendError([
470 + 'message' => __('Lesson is not on published state.', 'fluent-community')
471 + ]);
472 + }
473 +
474 + if (!LessonVideoGateService::isGatedLesson($lesson)) {
475 + return [
476 + 'message' => __('This lesson does not require video completion.', 'fluent-community'),
477 + 'is_gated' => false,
478 + 'watched' => false
479 + ];
480 + }
481 +
482 + $watchedPercent = min(100, absint($request->get('watched_percent')));
483 + $threshold = LessonVideoGateService::getThreshold($lesson);
484 +
485 + if ($watchedPercent < $threshold) {
486 + return $this->sendError([
487 + /* translators: %d is the watched percentage required to complete the lesson */
488 + 'message' => sprintf(__('Please watch at least %d%% of the video.', 'fluent-community'), $threshold)
489 + ]);
490 + }
491 +
492 + LessonVideoGateService::markWatched($lesson, get_current_user_id());
493 +
494 + return [
495 + 'message' => __('Video watch progress has been recorded.', 'fluent-community'),
496 + 'is_gated' => true,
497 + 'watched' => true
498 + ];
499 + }
500 +
501 + public function resetMyProgress(Request $request, $courseId)
502 + {
503 + $course = Course::findOrFail($courseId);
504 +
505 + if ($course->status !== 'published') {
506 + return $this->sendError([
507 + 'message' => __('Course is not in published state.', 'fluent-community')
508 + ]);
509 + }
510 +
511 + if (!CourseHelper::isEnrolled($courseId)) {
512 + return $this->sendError([
513 + 'message' => __('Please enroll this course first', 'fluent-community')
514 + ]);
515 + }
516 +
517 + CourseHelper::resetCourseProgress($courseId, get_current_user_id());
518 +
519 + return [
520 + 'message' => __('Your course progress has been reset.', 'fluent-community'),
521 + 'track' => [
522 + 'completed_lessons' => [],
523 + 'isEnrolled' => true,
524 + 'progress' => 0
525 + ]
526 + ];
527 + }
528 +
529 + public function getAllCourses(Request $request)
530 + {
531 + $user = $this->getUser();
532 + $isCourseCreator = $user && $user->hasCourseCreatorAccess();
533 +
534 + $coursesQuery = Course::where(function ($q) use ($isCourseCreator, $user) {
535 + if ($isCourseCreator) {
536 + $q->where('status', 'published')
537 + ->orWhere('created_by', $user->ID);
538 + } else {
539 + $q->where('status', 'published');
540 + }
541 + });
542 +
543 + if (!($user && $user->isCommunityModerator())) {
544 + $userId = get_current_user_id();
545 + $coursesQuery->where(function ($q) use ($userId) {
546 + $q->whereIn('privacy', ['public', 'private'])
547 + ->orWhereHas('space_pivot', function ($sub) use ($userId) {
548 + $sub->where('user_id', $userId)
549 + ->where('role', 'student');
550 + })
551 + ->orWhere('created_by', $userId);
552 + });
553 + }
554 +
555 + $courses = $coursesQuery->with(['creator'])->paginate();
556 +
557 + $formattedCourses = [];
558 + foreach ($courses as $course) {
559 + $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();
560 + $course->lessonsCount = CourseLesson::where('space_id', $course->id)->count();
561 +
562 + if (Arr::get($course->settings, 'hide_members_count') != 'yes') {
563 + $course->studentsCount = SpaceUserPivot::where('space_id', $course->id)->count();
564 + } else {
565 + $course->studentsCount = 0;
566 + }
567 +
568 + $showInstructorView = Arr::get($course->settings, 'hide_instructor_view') != 'yes';
569 + $showStudentCount = Arr::get($course->settings, 'show_instructor_students_count') == 'yes';
570 + if ($showInstructorView) {
571 + if ($course->creator) {
572 + $creatorCourseIds = Course::where('created_by', $course->creator->user_id)->pluck('id');
573 + $course->creator->total_courses = count($creatorCourseIds);
574 + if ($showStudentCount) {
575 + $course->creator->total_students = SpaceUserPivot::whereIn('space_id', $creatorCourseIds)->distinct('user_id')->count('user_id');
576 + }
577 + if ($course->creator->short_description) {
578 + $course->creator->short_description_rendered = wp_kses_post(FeedsHelper::mdToHtml($course->creator->short_description));
579 + }
580 + }
581 + }
582 +
583 + $formattedCourses[] = $this->processCourse($course, $course->isCourseAdmin($user));
584 + }
585 +
586 + return apply_filters('fluent_community/all_courses_api_response', [
587 + 'courses' => $formattedCourses,
588 + 'total' => $courses->total()
589 + ], $request->all());
277 590 }
278 591 }