From f6ff729316ff0786740cac4e8aa9073a85b2602d Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 7 Aug 2025 18:22:57 +0100 Subject: [PATCH] Added new generic files upload controller Signed-off-by: snipe --- .../Controllers/UploadedFilesController.php | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 app/Http/Controllers/UploadedFilesController.php diff --git a/app/Http/Controllers/UploadedFilesController.php b/app/Http/Controllers/UploadedFilesController.php new file mode 100644 index 0000000000..30e9df0698 --- /dev/null +++ b/app/Http/Controllers/UploadedFilesController.php @@ -0,0 +1,209 @@ + Accessory::class, + 'asset_maintenances' => AssetMaintenance::class, + 'assets' => Asset::class, + 'components' => Component::class, + 'consumables' => Consumable::class, + 'hardware' => Asset::class, + 'licenses' => License::class, + 'locations' => Location::class, + 'models' => AssetModel::class, + 'users' => User::class, + ]; + + static $map_storage_path = [ + 'accessories' => 'private_uploads/accessories/', + 'asset_maintenances' => 'private_uploads/asset_maintenances/', + 'assets' => 'private_uploads/assets/', + 'components' => 'private_uploads/components/', + 'consumables' => 'private_uploads/consumables/', + 'hardware' => 'private_uploads/assets/', + 'licenses' => 'private_uploads/licenses/', + 'locations' => 'private_uploads/locations/', + 'models' => 'private_uploads/assetmodels/', + 'users' => 'private_uploads/users/', + ]; + + static $map_file_prefix= [ + 'accessories' => 'accessory', + 'asset_maintenance' => 'asset', + 'assets' => 'asset', + 'components' => 'component', + 'consumables' => 'consumable', + 'hardware' => 'asset', + 'licenses' => 'license', + 'locations' => 'location', + 'models' => 'model', + 'users' => 'user', + ]; + + /** + * Accepts a POST to upload a file to the server. + * + * @param \App\Http\Requests\UploadFileRequest $request + * @param string $object_type the type of object to upload the file to + * @param int $id the ID of the object to store so we can check permisisons + * @since [v8.2.2] + * @author [A. Gianotto ] + */ + public function store(UploadFileRequest $request, $object_type, $id) : RedirectResponse + { + + // Check the permissions to make sure the user can view the object + $object = self::$map_object_type[$object_type]::find($id); + $this->authorize('update', $object); + + if (!$object) { + return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object')); + } + + // If the file storage directory doesn't exist, create it + if (! Storage::exists(self::$map_storage_path[$object_type])) { + Storage::makeDirectory(self::$map_storage_path[$object_type], 775); + } + + + if ($request->hasFile('file')) { + // Loop over the attached files and add them to the object + foreach ($request->file('file') as $file) { + $file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file); + $files[] = $file_name; + $object->logUpload($file_name, $request->get('notes')); + } + + $files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded') + ->where('item_type', '=', self::$map_object_type[$object_type]) + ->where('item_id', '=', $id)->whereIn('filename', $files) + ->get(); + + return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.upload.success', count($files))); + } + + // No files were submitted + return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.nofiles')); + } + + + + /** + * Check for permissions and display the file. + * This isn't currently used, but is here for future use. + * + * @param \App\Http\Requests\UploadFileRequest $request + * @param string $object_type the type of object to upload the file to + * @param int $id the ID of the object to delete from so we can check permisisons + * @param $file_id the ID of the file to show from the action_logs table + * @since [v8.2.2] + * @author [A. Gianotto ] + */ + public function show($object_type, $id, $file_id) : RedirectResponse | StreamedResponse | Storage | StorageHelper | BinaryFileResponse + { + // Check the permissions to make sure the user can view the object + $object = self::$map_object_type[$object_type]::find($id); + $this->authorize('view', $object); + + if (!$object) { + return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object')); + } + + + // Check that the file being requested exists for the object + if (! $log = Actionlog::whereNotNull('filename')->where('item_type', self::$map_object_type[$object_type])->where('item_id', $object->id)->find($file_id)) + { + return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.invalid_id')); + } + + + if (! Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename)) + { + return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.file_not_found')); + } + + if (request('inline') == 'true') { + $headers = [ + 'Content-Disposition' => 'inline', + ]; + return Storage::download(self::$map_storage_path[$object_type].'/'.$log->filename, $log->filename, $headers); + } + + return StorageHelper::downloader(self::$map_storage_path[$object_type].'/'.$log->filename); + + } + + /** + * Delete the associated file + * + * @param \App\Http\Requests\UploadFileRequest $request + * @param string $object_type the type of object to upload the file to + * @param int $id the ID of the object to delete from so we can check permisisons + * @param $file_id the ID of the file to delete from the action_logs table + * @since [v8.2.2] + * @author [A. Gianotto ] + */ + public function destroy($object_type, $id, $file_id) : RedirectResponse + { + + // Check the permissions to make sure the user can view the object + $object = self::$map_object_type[$object_type]::find($id); + $this->authorize('update', self::$map_object_type[$object_type]); + + if (!$object) { + return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object')); + } + + + // Check for the file + $log = Actionlog::find($file_id)->where('item_type', self::$map_object_type[$object_type]) + ->where('item_id', $object->id)->first(); + + if ($log) { + // Check the file actually exists, and delete it + if (Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename)) { + Storage::delete(self::$map_storage_path[$object_type].'/'.$log->filename); + } + // Delete the record of the file + if ($log->delete()) { + return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.success', 1)); + } + + } + + // The file doesn't seem to really exist, so report an error + return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.error', 1)); + + } + +}