PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.0
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 +387 -73 1.0.992.10.0 View file →
@@ -3,14 +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\Services\Helper;
7 8 use FluentCommunity\App\Services\LockscreenService;
8 9 use FluentCommunity\Framework\Http\Request\Request;
10 +use FluentCommunity\Framework\Support\Arr;
9 11 use FluentCommunity\Modules\Course\Model\Course;
10 12 use FluentCommunity\Modules\Course\Model\CourseLesson;
11 13 use FluentCommunity\Modules\Course\Model\CourseTopic;
14 +use FluentCommunity\App\Services\FeedsHelper;
12 15 use FluentCommunity\Modules\Course\Services\CourseHelper;
16 +use FluentCommunity\Modules\Course\Services\LessonVideoGateService;
13 17
14 18 class CourseController extends Controller
15 19 {
16 20 public function getCourses(Request $request)
@@ -16,33 +20,43 @@
16 20 public function getCourses(Request $request)
17 21 {
18 22 $user = $this->getUser();
19 23 $isCourseCreator = $user && $user->hasCourseCreatorAccess();
24 + $enrolledIds = CourseHelper::getEnrolledCourseIds();
20 25
21 - if ($request->get('type') == 'enrolled') {
22 - $courses = Course::searchBy($request->get('search'))
23 - ->where('status', 'published')
24 - ->orderBy('title', 'ASC')
25 - ->byPostTopic($request->get('topic_slug'))
26 - ->whereIn('id', CourseHelper::getEnrolledCourseIds())
27 - ->paginate();
28 - } else {
29 - $courses = Course::searchBy($request->get('search'))
30 - ->when(!$isCourseCreator, 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 {
31 37 $q->where('status', 'published');
32 - })
33 - ->byPostTopic($request->get('topic_slug'))
34 - ->orderBy('title', 'ASC')
35 - ->where(function ($q) {
36 - $q->whereIn('privacy', ['public', 'private']);
37 - if ($enrolledIds = CourseHelper::getEnrolledCourseIds()) {
38 - $q->orWhereIn('id', $enrolledIds);
39 - }
40 - })
41 - ->paginate();
42 - }
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();
43 58
44 -
45 59 foreach ($courses as $course) {
46 60 $course->isEnrolled = CourseHelper::isEnrolled($course->id);
47 61 if ($course->isEnrolled) {
48 62 $course->progress = CourseHelper::getCourseProgress($course->id);
@@ -53,57 +67,166 @@
53 67 }
54 68
55 69 $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();
56 70 $course->lessonsCount = CourseLesson::where('space_id', $course->id)->count();
57 - $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]);
58 78 }
59 79
60 - return [
80 + $data = [
61 81 'courses' => $courses,
62 - 'course_categories' => $request->get('with_categories') ? CourseHelper::getCourseCategories() : []
82 + 'course_categories' => $request->get('with_categories') ? CourseHelper::getCourseCategories() : []
63 83 ];
84 +
85 + return apply_filters('fluent_community/courses_api_response', $data, $request->all());
64 86 }
65 87
66 88 public function getCourse(Request $request, $courseId)
67 89 {
68 90 $user = $this->getUser();
69 - $isCourseCreator = $user && $user->hasCourseCreatorAccess();
70 91
71 - $course = Course::when(!$isCourseCreator, function ($q) {
72 - $q->where('status', 'published');
73 - })->find($courseId);
92 + $course = Course::findOrFail($courseId);
93 + /** @var Course $course */
74 94
75 - if (!$course) {
95 + $isCourseCreator = $course->isCourseAdmin($user);
96 +
97 + if ($course->status !== 'published' && !$isCourseCreator) {
76 98 return $this->sendError([
77 - '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')
78 100 ]);
79 101 }
80 102
81 - return $this->processCourse($course, $isCourseCreator);
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());
82 108 }
83 109
84 110 public function getCourseBySlug(Request $request, $slug)
85 111 {
86 112 $user = $this->getUser();
87 - $isCourseCreator = $user && $user->hasCourseCreatorAccess();
88 113
89 - $course = Course::when(!$isCourseCreator, function ($q) {
90 - $q->where('status', 'published');
91 - })->where('slug', $slug)->firstOrFail();
114 + $course = Course::where('slug', $slug)->firstOrFail();
115 + /** @var Course $course */
92 116
93 - if (!$course) {
117 + $isCourseCreator = $course->isCourseAdmin($user);
118 +
119 + if ($course->status !== 'published' && !$isCourseCreator) {
94 120 return $this->sendError([
95 - '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')
96 122 ]);
97 123 }
98 124
99 - return $this->processCourse($course, $isCourseCreator);
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());
100 146 }
101 147
102 - private function processCourse($course, $isCourseCreator)
148 + public function getLessonBySlug(Request $request, $courseSlug, $lessonSlug)
103 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 + {
104 226 $sections = CourseTopic::where('space_id', $course->id)
105 227 ->orderBy('priority', 'ASC')
228 + ->orderBy('id', 'ASC')
106 229 ->with(['lessons' => function ($query) use ($isCourseCreator) {
107 230 if (!$isCourseCreator) {
108 231 $query->where('status', 'published');
109 232 }
@@ -110,22 +233,40 @@
110 233 }])
111 234 ->get();
112 235
113 236 $enrollment = CourseHelper::getCourseEnrollment($course->id);
114 - $formattedSections = [];
115 237
238 + $currentUser = Helper::getCurrentUser();
239 +
116 240 if ($course->privacy == 'private' && !$enrollment) {
117 - $course->lockscreen_config = LockscreenService::getLockscreenConfig($course);
241 + $course->lockscreen_config = LockscreenService::getLockscreenConfig($course, null, true);
118 242 }
119 243
120 244 if ($course->privacy == 'secret' && !$enrollment && !$isCourseCreator) {
121 245 return $this->sendError([
122 - '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')
123 247 ]);
124 248 }
125 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 +
126 263 $courseType = $course->getCourseType();
127 264
265 + $hasPublicViewAccess = $course->privacy == 'public' && Arr::get($course->settings, 'public_lesson_view') == 'yes' && $courseType == 'self_paced';
266 +
267 + $formattedSections = [];
268 +
128 269 foreach ($sections as $section) {
129 270 if ($section->lessons->isEmpty()) {
130 271 continue;
131 272 }
@@ -134,9 +275,9 @@
134 275 $unlockDate = '';
135 276
136 277 if ($hasAcessSectionAcess) {
137 278 $unlockDate = CourseHelper::getSectionAccessDate($section, $courseType, $enrollment);
138 - if (!$unlockDate || strtotime($unlockDate) > current_time('timestamp')) {
279 + if ($unlockDate && strtotime($unlockDate) > current_time('timestamp')) {
139 280 $hasAcessSectionAcess = false;
140 281 } else {
141 282 $unlockDate = null;
142 283 }
@@ -141,32 +282,40 @@
141 282 $unlockDate = null;
142 283 }
143 284 }
144 285
286 + $sectionCtx = [
287 + 'enrollment' => $enrollment,
288 + 'is_admin' => $isCourseCreator,
289 + 'has_section_access' => $hasAcessSectionAcess,
290 + 'has_public_access' => $hasPublicViewAccess,
291 + ];
292 +
145 293 $formattedLessons = [];
146 294 foreach ($section->lessons as $lesson) {
147 - if ($hasAcessSectionAcess || $isCourseCreator) {
148 - $content = $lesson->message_rendered;
149 - if (!$content && $lesson->message) {
150 - $content = apply_filters('widget_block_content', do_blocks($lesson->message));
151 - }
152 - } else {
153 - $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;
154 313 }
155 314
156 - $formattedLessons[] = [
157 - 'id' => $lesson->id,
158 - 'title' => $lesson->title,
159 - 'content' => $content,
160 - 'slug' => $lesson->slug,
161 - 'course_id' => $lesson->space_id,
162 - 'section_id' => $lesson->parent_id,
163 - 'created_at' => $lesson->created_at,
164 - 'meta' => $lesson->meta,
165 - 'comments_count' => $lesson->comments_count,
166 - 'is_locked' => !$hasAcessSectionAcess && !$isCourseCreator,
167 - 'unclock_date' => $unlockDate
168 - ];
315 + $formattedLesson['lazy_load'] = $isLazyLoad;
316 +
317 + $formattedLessons[] = $formattedLesson;
169 318 }
170 319
171 320 $formattedSections[] = [
172 321 'id' => $section->id,
@@ -196,14 +345,19 @@
196 345 'message' => __('You need to login to enroll in this course.', 'fluent-community')
197 346 ]);
198 347 }
199 348
200 - $isCourseCreator = $user->hasCourseCreatorAccess();
201 - $course = Course::when(!$isCourseCreator, function ($q) {
202 - $q->where('status', 'published');
203 - })->findOrFail($courseId);
349 + $course = Course::findOrFail($courseId);
350 + /** @var Course $course */
204 351
352 + $isCourseCreator = $course->isCourseAdmin($user);
205 353
354 + if ($course->status !== 'published' && !$isCourseCreator) {
355 + return $this->sendError([
356 + 'message' => __('Course not found. maybe the course is not published yet!', 'fluent-community')
357 + ]);
358 + }
359 +
206 360 if (!$isCourseCreator && $course->privacy != 'public') {
207 361 return $this->sendError([
208 362 'message' => __('You are not allowed to enroll in this course.', 'fluent-community')
209 363 ]);
@@ -236,9 +390,9 @@
236 390
237 391
238 392 if (!CourseHelper::isEnrolled($courseId)) {
239 393 return $this->sendError([
240 - 'message' => 'You are not enrolled in this action.'
394 + 'message' => __('Please enroll this course first', 'fluent-community')
241 395 ]);
242 396 }
243 397
244 398 $lesson = CourseLesson::where('space_id', $courseId)
@@ -247,9 +401,9 @@
247 401 ->first();
248 402
249 403 if (!$lesson) {
250 404 return $this->sendError([
251 - 'message' => 'Lesson is not on published state.'
405 + 'message' => __('Lesson is not on published state.', 'fluent-community')
252 406 ]);
253 407 }
254 408
255 409 $state = $request->get('state');
@@ -255,23 +409,183 @@
255 409 $state = $request->get('state');
256 410
257 411 if (!in_array($state, ['completed', 'incomplete'])) {
258 412 return $this->sendError([
259 - 'message' => 'Invalid state.'
413 + 'message' => __('Invalid state.', 'fluent-community')
260 414 ]);
261 415 }
262 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 +
263 432 CourseHelper::updateLessonCompletion($lesson, get_current_user_id(), $state);
264 433 $track = CourseHelper::getCourseProgressTrack($courseId);
265 434 $isCompleted = $track['progress'] == 100;
266 435
267 436 if ($isCompleted) {
268 - CourseHelper::completeCourse($course, get_current_user_id());
437 + CourseHelper::completeCourse($course, $lesson, get_current_user_id());
269 438 }
270 439
271 440 return [
272 - 'message' => 'Lesson completion state updated.',
441 + 'message' => __('Lesson completion state updated.', 'fluent-community'),
273 442 'track' => $track,
274 443 'is_completed' => $isCompleted
275 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());
276 590 }
277 591 }