PM_Console/backend/app/Http/Controllers/Api/FileController.php

171 خطوط
6.2 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\FileResource;
use App\Models\Comment;
use App\Models\File;
use App\Models\Meeting;
use App\Models\Project;
use App\Models\Task;
use App\Services\ResourceAccessService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class FileController extends Controller
{
public function __construct(private readonly ResourceAccessService $resourceAccess) {}
public function index(Request $request): JsonResponse
{
try {
$query = $this->resourceAccess->files($request->user())->with('user');
if ($request->filled('fileable_type')) {
$query->where('fileable_type', $request->fileable_type);
}
if ($request->filled('fileable_id')) {
$query->where('fileable_id', $request->fileable_id);
}
$perPage = $request->input('per_page', 15);
$files = $query->orderBy('created_at', 'desc')->paginate($perPage);
return response()->json([
'success' => true,
'data' => FileResource::collection($files),
'meta' => [
'current_page' => $files->currentPage(),
'last_page' => $files->lastPage(),
'per_page' => $files->perPage(),
'total' => $files->total(),
],
'message' => 'لیست فایل‌ها',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت فایل‌ها',
], 500);
}
}
public function store(Request $request): JsonResponse
{
try {
$request->validate([
'file' => 'required|file|max:10240|mimes:pdf,doc,docx,xls,xlsx,ppt,pptx,txt,csv,jpg,jpeg,png,webp,zip',
'fileable_type' => 'nullable|string|in:App\\Models\\Project,App\\Models\\Task,App\\Models\\Comment,App\\Models\\Meeting',
'fileable_id' => 'nullable|integer',
'project_id' => 'nullable|exists:projects,id',
]);
$fileableType = $request->fileable_type;
$fileableId = $request->fileable_id;
if ($request->filled('project_id')) {
$fileableType = Project::class;
$fileableId = $request->project_id;
}
if (! $fileableType || ! $fileableId) {
return response()->json([
'success' => false,
'message' => 'انتخاب محل آپلود فایل الزامی است',
], 422);
}
$allowed = match ($fileableType) {
Project::class => $this->resourceAccess->projects($request->user())->whereKey($fileableId)->exists(),
Task::class => $this->resourceAccess->tasks($request->user())->whereKey($fileableId)->exists(),
Meeting::class => $this->resourceAccess->meetings($request->user())->whereKey($fileableId)->exists(),
Comment::class => $this->resourceAccess->comments($request->user())->whereKey($fileableId)->exists(),
default => false,
};
abort_unless($allowed, 403, 'شما به محل انتخاب‌شده برای فایل دسترسی ندارید.');
$uploadedFile = $request->file('file');
$originalName = $uploadedFile->getClientOriginalName();
$extension = strtolower($uploadedFile->getClientOriginalExtension());
$name = Str::uuid()->toString().($extension ? ".{$extension}" : '');
$path = $uploadedFile->storeAs('files', $name, 'local');
$file = File::create([
'name' => $name,
'original_name' => $originalName,
'path' => $path,
'mime_type' => $uploadedFile->getMimeType(),
'size' => $uploadedFile->getSize(),
'fileable_id' => $fileableId,
'fileable_type' => $fileableType,
'user_id' => $request->user()->id,
]);
$file->load('user');
return response()->json([
'success' => true,
'data' => new FileResource($file),
'message' => 'فایل با موفقیت آپلود شد',
], 201);
} catch (ValidationException $e) {
throw $e;
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در آپلود فایل',
], 500);
}
}
public function show(File $file): JsonResponse
{
try {
$disk = Storage::disk('local')->exists($file->path) ? 'local' : 'public';
if (! Storage::disk($disk)->exists($file->path)) {
return response()->json([
'success' => false,
'message' => 'فایل یافت نشد',
], 404);
}
$filePath = Storage::disk($disk)->path($file->path);
return response()->download($filePath, $file->original_name);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت فایل',
], 500);
}
}
public function destroy(File $file): JsonResponse
{
try {
foreach (['local', 'public'] as $disk) {
if (Storage::disk($disk)->exists($file->path)) {
Storage::disk($disk)->delete($file->path);
break;
}
}
$file->delete();
return response()->json([
'success' => true,
'message' => 'فایل حذف شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در حذف فایل',
], 500);
}
}
}