authorizeWrite('settings'); $repositories = StorageRepository::orderBy('ordine')->get(); if ($request->ajax()) { return response()->json($repositories); } return view('storage-repositories.index', compact('repositories')); } public function store(Request $request): RedirectResponse { $this->authorizeWrite('settings'); $validated = $request->validate([ 'nome' => 'required|string|max:255', 'tipo' => 'required|string|in:webdav,google_drive', 'config' => 'required|array', 'is_active' => 'boolean', 'ordine' => 'nullable|integer|min:0', ]); $maxOrdine = StorageRepository::max('ordine') ?? 0; $validated['ordine'] ??= $maxOrdine + 1; $validated['config'] = $this->repoService->encryptSensitiveConfig($validated['config'], $validated['tipo']); StorageRepository::create($validated); return redirect('/impostazioni#repository')->with('success', 'Repository creato.'); } public function update(Request $request, StorageRepository $storageRepository): RedirectResponse { $this->authorizeWrite('settings'); $validated = $request->validate([ 'nome' => 'required|string|max:255', 'tipo' => 'required|string|in:webdav,google_drive', 'config' => 'required|array', 'is_active' => 'boolean', 'ordine' => 'nullable|integer|min:0', ]); $validated['config'] = $this->repoService->encryptSensitiveConfig($validated['config'], $validated['tipo']); $storageRepository->update($validated); return redirect('/impostazioni#repository')->with('success', 'Repository aggiornato.'); } public function destroy(StorageRepository $storageRepository): JsonResponse|RedirectResponse { $this->authorizeDelete('settings'); $docCount = $storageRepository->documenti()->count(); if ($docCount > 0) { $message = "Impossibile eliminare: {$docCount} documenti associati a questo repository."; if (request()->expectsJson()) { return response()->json(['success' => false, 'message' => $message], 409); } return redirect('/impostazioni#repository')->with('error', $message); } $storageRepository->delete(); if (request()->expectsJson()) { return response()->json(['success' => true]); } return redirect('/impostazioni#repository')->with('success', 'Repository eliminato.'); } public function test(StorageRepository $storageRepository): JsonResponse { $this->authorizeWrite('settings'); $result = $this->repoService->testConnection($storageRepository); return response()->json($result); } public function browse(Request $request, StorageRepository $storageRepository): JsonResponse { $this->authorizeRead('documenti'); $path = $request->get('path', '/'); $contents = $this->repoService->listContents($storageRepository, $path); return response()->json([ 'success' => true, 'contents' => $contents, 'path' => $path, 'repository' => [ 'id' => $storageRepository->id, 'nome' => $storageRepository->nome, 'tipo' => $storageRepository->tipo, ], ]); } public function reorder(Request $request): JsonResponse { $this->authorizeWrite('settings'); $order = $request->input('order', []); foreach ($order as $index => $id) { StorageRepository::where('id', $id)->update(['ordine' => $index]); } return response()->json(['success' => true]); } public function downloadRemote(StorageRepository $storageRepository, Request $request): StreamedResponse { $this->authorizeRead('documenti'); $path = $request->get('path'); if (!$path) { abort(400, 'Path required'); } $filesystem = $this->repoService->buildFilesystem($storageRepository); if (!$filesystem || !$filesystem->fileExists($path)) { abort(404); } $stream = $filesystem->readStream($path); if (!$stream) { abort(404); } $mimeType = $filesystem->mimeType($path) ?? 'application/octet-stream'; $basename = basename($path); return response()->stream(function () use ($stream) { fpassthru($stream); fclose($stream); }, 200, [ 'Content-Type' => $mimeType, 'Content-Disposition' => 'attachment; filename="' . $basename . '"', ]); } public function previewRemote(StorageRepository $storageRepository, Request $request): StreamedResponse { $this->authorizeRead('documenti'); $path = $request->get('path'); if (!$path) { abort(400, 'Path required'); } $filesystem = $this->repoService->buildFilesystem($storageRepository); if (!$filesystem || !$filesystem->fileExists($path)) { abort(404); } $stream = $filesystem->readStream($path); if (!$stream) { abort(404); } $mimeType = $filesystem->mimeType($path) ?? 'application/octet-stream'; $basename = basename($path); return response()->stream(function () use ($stream) { fpassthru($stream); fclose($stream); }, 200, [ 'Content-Type' => $mimeType, 'Content-Disposition' => 'inline; filename="' . $basename . '"', ]); } }