171 خطوط
6.2 KiB
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);
|
|
}
|
|
}
|
|
}
|