Files
bogazici-api/app/Http/Controllers/Api/Admin/UploadController.php
2026-03-27 10:41:54 +03:00

139 lines
4.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use OpenApi\Attributes as OA;
class UploadController extends Controller
{
#[OA\Post(
path: '/api/admin/upload',
summary: 'Dosya yükle',
description: 'Görsel veya video dosyası yükler. Görseller max 5MB, videolar max 100MB. Modül bazlı klasörleme destekler.',
security: [['sanctum' => []]],
tags: ['Upload'],
requestBody: new OA\RequestBody(
required: true,
content: new OA\MediaType(
mediaType: 'multipart/form-data',
schema: new OA\Schema(
required: ['file'],
properties: [
new OA\Property(property: 'file', type: 'string', format: 'binary', description: 'Görsel veya video dosyası'),
new OA\Property(property: 'type', type: 'string', enum: ['image', 'video'], description: 'Dosya tipi'),
new OA\Property(property: 'folder', type: 'string', description: 'Modül klasörü (hero-slides, courses, vb.)'),
],
),
),
),
responses: [
new OA\Response(response: 201, description: 'Dosya yüklendi', content: new OA\JsonContent(
properties: [
new OA\Property(property: 'data', type: 'object', properties: [
new OA\Property(property: 'path', type: 'string'),
new OA\Property(property: 'url', type: 'string'),
]),
],
)),
new OA\Response(response: 422, description: 'Validasyon hatası'),
],
)]
public function store(Request $request): JsonResponse
{
$type = $request->input('type', 'image');
if ($type === 'video') {
return $this->storeVideo($request);
}
return $this->storeImage($request);
}
/**
* @var list<string>
*/
private const ALLOWED_FOLDERS = [
'images',
'videos',
'hero-slides',
'settings',
'pages',
'courses',
'announcements',
'categories',
];
private function resolveFolder(Request $request, string $default): string
{
$folder = $request->input('folder', $default);
if (! in_array($folder, self::ALLOWED_FOLDERS, true)) {
$folder = $default;
}
return $folder;
}
private function storeImage(Request $request): JsonResponse
{
$request->validate([
'file' => ['required', 'file', 'image', 'max:5120'],
'folder' => ['sometimes', 'string'],
], [
'file.required' => 'Dosya zorunludur.',
'file.image' => 'Dosya bir görsel (jpg, png, gif, svg, webp) olmalıdır.',
'file.max' => 'Dosya boyutu en fazla 5MB olabilir.',
]);
$folder = $this->resolveFolder($request, 'images');
$file = $request->file('file');
$filename = Str::uuid().'.'.$file->getClientOriginalExtension();
$directory = public_path('uploads/'.$folder);
$file->move($directory, $filename);
$relativePath = 'uploads/'.$folder.'/'.$filename;
return response()->json([
'data' => [
'path' => $relativePath,
'url' => url($relativePath),
],
], 201);
}
private function storeVideo(Request $request): JsonResponse
{
$request->validate([
'file' => ['required', 'file', 'mimes:mp4,webm,mov,avi,mkv', 'max:102400'],
'folder' => ['sometimes', 'string'],
], [
'file.required' => 'Dosya zorunludur.',
'file.mimes' => 'Dosya bir video (mp4, webm, mov, avi, mkv) olmalıdır.',
'file.max' => 'Video boyutu en fazla 100MB olabilir.',
]);
$folder = $this->resolveFolder($request, 'videos');
$file = $request->file('file');
$filename = Str::uuid().'.'.$file->getClientOriginalExtension();
$directory = public_path('uploads/'.$folder);
$file->move($directory, $filename);
$relativePath = 'uploads/'.$folder.'/'.$filename;
return response()->json([
'data' => [
'path' => $relativePath,
'url' => url($relativePath),
],
], 201);
}
}