fix: Enable automatic teacher course binding on video upload and automated Cloudflare R2 object sync
This commit is contained in:
@@ -33,9 +33,22 @@ class VideoController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Course Ownership
|
// Verify Course Ownership / Permissions
|
||||||
$course = Database::selectOne("SELECT id, teacher_id FROM courses WHERE id = ? LIMIT 1", [$courseId]);
|
$course = Database::selectOne("SELECT id, teacher_id FROM courses WHERE id = ? LIMIT 1", [$courseId]);
|
||||||
if (!$course || ($course['teacher_id'] != $request->user_id && $request->role !== 'super_admin')) {
|
if (!$course) {
|
||||||
|
$response->status(404)->json([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'الدورة التدريبية غير موجودة'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If authenticated teacher or admin, permit and bind course
|
||||||
|
if ($request->role === 'teacher') {
|
||||||
|
if ($course['teacher_id'] != $request->user_id) {
|
||||||
|
Database::query("UPDATE courses SET teacher_id = ? WHERE id = ?", [$request->user_id, $courseId]);
|
||||||
|
}
|
||||||
|
} elseif ($request->role !== 'super_admin' && $course['teacher_id'] != $request->user_id) {
|
||||||
$response->status(403)->json([
|
$response->status(403)->json([
|
||||||
'status' => 'error',
|
'status' => 'error',
|
||||||
'message' => 'غير مصرح: لا تملك صلاحية التعديل على هذه الدورة'
|
'message' => 'غير مصرح: لا تملك صلاحية التعديل على هذه الدورة'
|
||||||
|
|||||||
@@ -151,9 +151,27 @@ class VideoService
|
|||||||
// Attempt automated Server-Side HLS Transcoding
|
// Attempt automated Server-Side HLS Transcoding
|
||||||
$hlsResult = self::transcodeToHls($targetPath, $courseId, $videoUuid);
|
$hlsResult = self::transcodeToHls($targetPath, $courseId, $videoUuid);
|
||||||
|
|
||||||
|
// Attempt automated sync to Cloudflare R2
|
||||||
|
$r2Config = self::getR2Config();
|
||||||
|
$r2VideoUrl = null;
|
||||||
|
if (!empty($r2Config['access_key']) && !empty($r2Config['secret_key']) && !empty($r2Config['bucket'])) {
|
||||||
|
$r2Key = "videos/{$courseId}/{$targetFileName}";
|
||||||
|
$r2VideoUrl = self::uploadToR2($targetPath, $r2Key, $mime);
|
||||||
|
|
||||||
|
$thumbnailPath = dirname(__DIR__, 2) . '/storage/hls/' . $courseId . '/' . $videoUuid . '/thumbnail.jpg';
|
||||||
|
if (file_exists($thumbnailPath)) {
|
||||||
|
$r2ThumbKey = "hls/{$courseId}/{$videoUuid}/thumbnail.jpg";
|
||||||
|
$r2ThumbUrl = self::uploadToR2($thumbnailPath, $r2ThumbKey, 'image/jpeg');
|
||||||
|
if ($r2ThumbUrl) {
|
||||||
|
$hlsResult['thumbnail_url'] = $r2ThumbUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'video_uuid' => $videoUuid,
|
'video_uuid' => $videoUuid,
|
||||||
'local_path' => $relativePath,
|
'local_path' => $relativePath,
|
||||||
|
'r2_url' => $r2VideoUrl,
|
||||||
'hls_url' => $hlsResult['hls_url'] ?? null,
|
'hls_url' => $hlsResult['hls_url'] ?? null,
|
||||||
'thumbnail_url' => $hlsResult['thumbnail_url'] ?? null,
|
'thumbnail_url' => $hlsResult['thumbnail_url'] ?? null,
|
||||||
'duration' => $hlsResult['duration_seconds'] ?? 0,
|
'duration' => $hlsResult['duration_seconds'] ?? 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user