119 lines
4.0 KiB
PHP
119 lines
4.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Academy;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\AcademyCourse;
|
|
use App\Models\AcademyLesson;
|
|
use App\Services\Academy\AcademyAccessService;
|
|
use App\Services\Academy\AcademyProgressService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
final class AcademyProgressController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly AcademyAccessService $access,
|
|
private readonly AcademyProgressService $progress,
|
|
) {
|
|
}
|
|
|
|
public function startLesson(Request $request): JsonResponse
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$validated = $request->validate([
|
|
'lesson_id' => ['required', 'integer', 'min:1'],
|
|
'course_id' => ['nullable', 'integer', 'min:1'],
|
|
]);
|
|
|
|
$lesson = AcademyLesson::query()->findOrFail((int) $validated['lesson_id']);
|
|
abort_unless($this->access->canAccessLesson($request->user(), $lesson), 403);
|
|
|
|
$courseId = $request->filled('course_id') ? (int) $validated['course_id'] : null;
|
|
if ($courseId !== null) {
|
|
$course = AcademyCourse::query()->published()->findOrFail($courseId);
|
|
abort_unless($course->courseLessons()->where('lesson_id', $lesson->id)->exists(), 403);
|
|
}
|
|
|
|
$record = $this->progress->startLesson($request->user(), (int) $lesson->id, $courseId, $request);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'status' => (string) $record->status,
|
|
]);
|
|
}
|
|
|
|
public function complete(Request $request, AcademyLesson $lesson): JsonResponse
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
abort_unless($this->access->canAccessLesson($request->user(), $lesson), 403);
|
|
|
|
$course = null;
|
|
|
|
if ($request->filled('course_id')) {
|
|
$course = AcademyCourse::query()->published()->find($request->integer('course_id'));
|
|
}
|
|
|
|
$record = $this->progress->markLessonComplete($request->user(), $lesson, $course, $request);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'completed' => true,
|
|
'completed_at' => $record->completed_at?->toISOString(),
|
|
]);
|
|
}
|
|
|
|
public function completeLesson(Request $request): JsonResponse
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$validated = $request->validate([
|
|
'lesson_id' => ['required', 'integer', 'min:1'],
|
|
'course_id' => ['nullable', 'integer', 'min:1'],
|
|
]);
|
|
|
|
$lesson = AcademyLesson::query()->findOrFail((int) $validated['lesson_id']);
|
|
|
|
return $this->complete($request, $lesson);
|
|
}
|
|
|
|
public function startCourse(Request $request): JsonResponse
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$validated = $request->validate([
|
|
'course_id' => ['required', 'integer', 'min:1'],
|
|
]);
|
|
|
|
$course = AcademyCourse::query()->published()->findOrFail((int) $validated['course_id']);
|
|
$record = $this->progress->startCourse($request->user(), (int) $course->id, $request);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'status' => (string) $record->status,
|
|
'progress_percent' => (int) $record->progress_percent,
|
|
]);
|
|
}
|
|
|
|
public function completeCourse(Request $request): JsonResponse
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$validated = $request->validate([
|
|
'course_id' => ['required', 'integer', 'min:1'],
|
|
]);
|
|
|
|
$course = AcademyCourse::query()->published()->findOrFail((int) $validated['course_id']);
|
|
$record = $this->progress->completeCourse($request->user(), (int) $course->id, $request);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'status' => (string) $record->status,
|
|
'progress_percent' => (int) $record->progress_percent,
|
|
'completed' => (string) $record->status === 'completed',
|
|
]);
|
|
}
|
|
} |