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 +116 -9 2.6.012.10.01 View file →
@@ -12,8 +12,9 @@
12 12 use FluentCommunity\Modules\Course\Model\CourseLesson;
13 13 use FluentCommunity\Modules\Course\Model\CourseTopic;
14 14 use FluentCommunity\App\Services\FeedsHelper;
15 15 use FluentCommunity\Modules\Course\Services\CourseHelper;
16 +use FluentCommunity\Modules\Course\Services\LessonVideoGateService;
16 17
17 18 class CourseController extends Controller
18 19 {
19 20 public function getCourses(Request $request)
@@ -88,8 +89,9 @@
88 89 {
89 90 $user = $this->getUser();
90 91
91 92 $course = Course::findOrFail($courseId);
93 + /** @var Course $course */
92 94
93 95 $isCourseCreator = $course->isCourseAdmin($user);
94 96
95 97 if ($course->status !== 'published' && !$isCourseCreator) {
@@ -109,8 +111,9 @@
109 111 {
110 112 $user = $this->getUser();
111 113
112 114 $course = Course::where('slug', $slug)->firstOrFail();
115 + /** @var Course $course */
113 116
114 117 $isCourseCreator = $course->isCourseAdmin($user);
115 118
116 119 if ($course->status !== 'published' && !$isCourseCreator) {
@@ -145,8 +148,9 @@
145 148 public function getLessonBySlug(Request $request, $courseSlug, $lessonSlug)
146 149 {
147 150 $user = $this->getUser();
148 151
152 + /** @var Course $course */
149 153 $course = Course::where('slug', $courseSlug)->firstOrFail();
150 154
151 155 $isCourseCreator = $course->isCourseAdmin($user);
152 156
@@ -205,9 +209,9 @@
205 209 $formattedLesson = CourseHelper::formatLessonData($course, $lesson, $user, [
206 210 'can_view' => $canViewLesson,
207 211 'parse_content' => $canViewLesson,
208 212 'is_locked' => !$canViewLesson && !$isCourseCreator,
209 - 'unclock_date' => $unlockDate,
213 + 'unlock_date' => $unlockDate,
210 214 'lock_type' => $lockType
211 215 ]);
212 216
213 217 $data = [
@@ -220,8 +224,9 @@
220 224 private function processCourse(Course $course, $isCourseCreator, $intendtedLessonSlug = '')
221 225 {
222 226 $sections = CourseTopic::where('space_id', $course->id)
223 227 ->orderBy('priority', 'ASC')
228 + ->orderBy('id', 'ASC')
224 229 ->with(['lessons' => function ($query) use ($isCourseCreator) {
225 230 if (!$isCourseCreator) {
226 231 $query->where('status', 'published');
227 232 }
@@ -297,9 +302,9 @@
297 302 $formattedLesson = CourseHelper::formatLessonData($course, $lesson, $currentUser, [
298 303 'can_view' => $canViewLesson,
299 304 'parse_content' => $parseContent,
300 305 'is_locked' => !$canViewLesson && !$isCourseCreator,
301 - 'unclock_date' => $unlockDate,
306 + 'unlock_date' => $unlockDate,
302 307 'lock_type' => $lockType
303 308 ]);
304 309
305 310 $isLazyLoad = !$parseContent;
@@ -341,8 +346,9 @@
341 346 ]);
342 347 }
343 348
344 349 $course = Course::findOrFail($courseId);
350 + /** @var Course $course */
345 351
346 352 $isCourseCreator = $course->isCourseAdmin($user);
347 353
348 354 if ($course->status !== 'published' && !$isCourseCreator) {
@@ -407,14 +413,21 @@
407 413 'message' => __('Invalid state.', 'fluent-community')
408 414 ]);
409 415 }
410 416
411 - $isAllowed = apply_filters('fluent_community/is_allowed_to_complete_lesson', true, $lesson);
417 + $isAllowed = apply_filters('fluent_community/is_allowed_to_complete_lesson', true, $lesson, $state);
412 418
413 419 if (!$isAllowed) {
414 - return $this->sendError([
420 + $errorData = [
415 421 'message' => __('You are not allowed to complete this lesson.', 'fluent-community')
416 - ]);
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);
417 430 }
418 431
419 432 CourseHelper::updateLessonCompletion($lesson, get_current_user_id(), $state);
420 433 $track = CourseHelper::getCourseProgressTrack($courseId);
@@ -430,14 +443,96 @@
430 443 'is_completed' => $isCompleted
431 444 ];
432 445 }
433 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 +
434 529 public function getAllCourses(Request $request)
435 530 {
436 531 $user = $this->getUser();
437 532 $isCourseCreator = $user && $user->hasCourseCreatorAccess();
438 533
439 - $courses = Course::where(function ($q) use ($isCourseCreator, $user) {
534 + $coursesQuery = Course::where(function ($q) use ($isCourseCreator, $user) {
440 535 if ($isCourseCreator) {
441 536 $q->where('status', 'published')
442 537 ->orWhere('created_by', $user->ID);
443 538 } else {
@@ -442,11 +537,23 @@
442 537 ->orWhere('created_by', $user->ID);
443 538 } else {
444 539 $q->where('status', 'published');
445 540 }
446 - })
447 - ->with(['creator'])
448 - ->paginate();
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();
449 556
450 557 $formattedCourses = [];
451 558 foreach ($courses as $course) {
452 559 $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();