177 lines
6.8 KiB
PHP
177 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Course;
|
|
|
|
use Illuminate\Http\Request;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Course\WatchHistory;
|
|
use App\Services\Course\CoursePlayerService;
|
|
use App\Services\Course\CourseReviewService;
|
|
use App\Services\Course\CourseService;
|
|
use App\Services\Course\CourseSectionService;
|
|
use App\Services\LiveClass\ZoomLiveService;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Inertia\Inertia;
|
|
|
|
class PlayerController extends Controller
|
|
{
|
|
public function __construct(
|
|
protected CourseService $courseService,
|
|
protected CoursePlayerService $coursePlay,
|
|
protected CourseSectionService $sectionService,
|
|
protected CourseReviewService $reviewService,
|
|
protected ZoomLiveService $zoomLiveService,
|
|
// protected AssignmentSubmissionService $submissionService,
|
|
) {}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$courses = $this->courseService->getCourses($request->all(), null, true);
|
|
|
|
return Inertia::render('courses/index', compact('courses'));
|
|
}
|
|
|
|
public function intWatchHistory(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
$watchHistory = $this->sectionService->initWatchHistory($request->course_id, 'lesson', $user->id);
|
|
|
|
return redirect()->route('course.player', [
|
|
'type' => $watchHistory->current_watching_type,
|
|
'watch_history' => $watchHistory->id,
|
|
'lesson_id' => $watchHistory->current_watching_id,
|
|
]);
|
|
}
|
|
|
|
public function course_player(Request $request, string $type, WatchHistory $watch_history, string $lesson_id)
|
|
{
|
|
try {
|
|
$user = Auth::user();
|
|
|
|
$watching_id = $lesson_id ?: $watch_history->current_watching_id;
|
|
$watching_type = in_array($type, ['lesson', 'quiz'], true) ? $type : ($watch_history->current_watching_type ?? 'lesson');
|
|
|
|
$course = $this->courseService->getUserCourseById($watch_history->course_id, $user);
|
|
$watching = $this->coursePlay->getWatchingLesson($watching_id, $watching_type);
|
|
$reviews = $this->reviewService->getReviews(['course_id' => $course->id, ...$request->all()], true);
|
|
$userReview = $this->reviewService->userReview($course->id, $user->id);
|
|
$totalReviews = $this->reviewService->totalReviews($course->id);
|
|
$zoomConfig = $this->zoomLiveService->zoomConfig;
|
|
|
|
$totalContent = 0;
|
|
|
|
foreach ($course->sections as $courseSection) {
|
|
$totalContent += count($courseSection->section_lessons) + count($courseSection->section_quizzes);
|
|
}
|
|
|
|
$watchHistory = $this->coursePlay->watchHistory($course, $watching_id, $watching_type, $user->id);
|
|
$section = $course->sections->firstWhere('id', $watchHistory->current_section_id);
|
|
|
|
// $submissions = null;
|
|
// if ($assignment) {
|
|
// $submissions = $this->submissionService->getSubmissions($assignment, $request->all());
|
|
// }
|
|
|
|
return Inertia::render('course-player/index', [
|
|
'type' => $type,
|
|
'course' => $course,
|
|
'section' => $section,
|
|
'reviews' => $reviews,
|
|
'watching' => $watching,
|
|
'totalContent' => $totalContent,
|
|
'watchHistory' => $watchHistory,
|
|
'userReview' => $userReview,
|
|
'totalReviews' => $totalReviews,
|
|
'zoomConfig' => $zoomConfig,
|
|
]);
|
|
} catch (ModelNotFoundException $th) {
|
|
$fallbackId = $watch_history->current_watching_id;
|
|
$fallbackType = $watch_history->current_watching_type;
|
|
$requestedType = $watching_type ?? $type;
|
|
|
|
if ($fallbackId && in_array($fallbackType, ['lesson', 'quiz'], true)) {
|
|
$isDifferentFromRequested = ((string) $fallbackId !== (string) $lesson_id) || ($fallbackType !== $requestedType);
|
|
|
|
if ($isDifferentFromRequested) {
|
|
try {
|
|
$this->coursePlay->getWatchingLesson((string) $fallbackId, $fallbackType);
|
|
|
|
return redirect()->route('course.player', [
|
|
'type' => $fallbackType,
|
|
'watch_history' => $watch_history->id,
|
|
'lesson_id' => $fallbackId,
|
|
]);
|
|
} catch (ModelNotFoundException $fallbackException) {
|
|
// Fall through to generic error below.
|
|
}
|
|
}
|
|
}
|
|
|
|
return redirect()->route('category.courses', ['category' => 'all'])->with('error', 'The requested content could not be found.');
|
|
} catch (\Throwable $th) {
|
|
return redirect()->route('category.courses', ['category' => 'all'])->with('error', $th->getMessage());
|
|
}
|
|
}
|
|
|
|
public function finish_course(WatchHistory $watch_history)
|
|
{
|
|
$completedItems = json_decode($watch_history->completed_watching, true) ?: [];
|
|
$lastItem = [
|
|
'id' => $watch_history->current_watching_id,
|
|
'type' => $watch_history->current_watching_type,
|
|
];
|
|
|
|
// Check if lastItem already exists in completedItems
|
|
$itemExists = false;
|
|
foreach ($completedItems as $item) {
|
|
if ((string)$item['id'] === (string)$lastItem['id'] && $item['type'] === $lastItem['type']) {
|
|
$itemExists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Add lastItem to completedItems if it doesn't exist
|
|
if (!$itemExists) {
|
|
$completedItems[] = $lastItem;
|
|
}
|
|
|
|
// Clean up duplicates and ensure consistent data types
|
|
$completedItems = $this->cleanupCompletedItems($completedItems);
|
|
|
|
$watch_history->completed_watching = json_encode($completedItems);
|
|
$watch_history->completion_date = now();
|
|
$watch_history->save();
|
|
|
|
return back()->with('success', 'Kurs erfolgreich abgeschlossen.');
|
|
}
|
|
|
|
/**
|
|
* Clean up completed items to remove duplicates and ensure consistent data types
|
|
*/
|
|
private function cleanupCompletedItems(array $completedItems): array
|
|
{
|
|
$cleaned = [];
|
|
$seen = [];
|
|
|
|
foreach ($completedItems as $item) {
|
|
// Ensure consistent data types (string for ID)
|
|
$normalizedItem = [
|
|
'id' => (string)$item['id'],
|
|
'type' => $item['type']
|
|
];
|
|
|
|
// Create unique key for duplicate checking
|
|
$key = $normalizedItem['id'] . '|' . $normalizedItem['type'];
|
|
|
|
// Only add if not already seen
|
|
if (!isset($seen[$key])) {
|
|
$seen[$key] = true;
|
|
$cleaned[] = $normalizedItem;
|
|
}
|
|
}
|
|
|
|
return $cleaned;
|
|
}
|
|
}
|