*/ public function orderedCourseLessons(AcademyCourse $course): Collection { return $course->courseLessons() ->with(['section', 'lesson.category']) ->get() ->filter(fn (AcademyCourseLesson $courseLesson): bool => $courseLesson->lesson instanceof AcademyLesson && (bool) $courseLesson->lesson->active && $courseLesson->lesson->published_at !== null && $courseLesson->lesson->published_at->lte(now())) ->sort(fn (AcademyCourseLesson $left, AcademyCourseLesson $right): int => $this->courseLessonSortKey($left) <=> $this->courseLessonSortKey($right)) ->values(); } /** * @return array */ private function courseLessonSortKey(AcademyCourseLesson $courseLesson): array { $section = $courseLesson->section; return [ $courseLesson->section_id === null ? 0 : 1, (int) ($section?->order_num ?? 0), (int) ($section?->id ?? 0), (int) ($courseLesson->order_num ?? 0), (int) $courseLesson->id, ]; } public function firstPublishedLesson(AcademyCourse $course): ?AcademyCourseLesson { return $this->orderedCourseLessons($course)->first(); } public function findCourseLesson(AcademyCourse $course, AcademyLesson $lesson): ?AcademyCourseLesson { return $this->orderedCourseLessons($course) ->first(fn (AcademyCourseLesson $courseLesson): bool => $courseLesson->lesson?->is($lesson) ?? false); } public function nextLesson(AcademyCourse $course, AcademyLesson $lesson): ?AcademyCourseLesson { $ordered = $this->orderedCourseLessons($course); $index = $ordered->search(fn (AcademyCourseLesson $courseLesson): bool => $courseLesson->lesson?->is($lesson) ?? false); return is_int($index) ? $ordered->get($index + 1) : null; } public function previousLesson(AcademyCourse $course, AcademyLesson $lesson): ?AcademyCourseLesson { $ordered = $this->orderedCourseLessons($course); $index = $ordered->search(fn (AcademyCourseLesson $courseLesson): bool => $courseLesson->lesson?->is($lesson) ?? false); return is_int($index) && $index > 0 ? $ordered->get($index - 1) : null; } }