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); } } }