diff --git a/app/Helpers/IconHelper.php b/app/Helpers/IconHelper.php index 668b01a9f6..8172f2bbbb 100644 --- a/app/Helpers/IconHelper.php +++ b/app/Helpers/IconHelper.php @@ -16,6 +16,7 @@ class IconHelper case 'clone': return 'far fa-clone'; case 'delete': + case 'upload deleted': return 'fas fa-trash'; case 'create': return 'fa-solid fa-plus'; diff --git a/app/Http/Controllers/Api/UploadedFilesController.php b/app/Http/Controllers/Api/UploadedFilesController.php index abf35652f9..a4a2de0520 100644 --- a/app/Http/Controllers/Api/UploadedFilesController.php +++ b/app/Http/Controllers/Api/UploadedFilesController.php @@ -51,11 +51,7 @@ class UploadedFilesController extends Controller ]; - $uploads = Actionlog::select('action_logs.*') - ->whereNotNull('filename') - ->where('item_type', self::$map_object_type[$object_type]) - ->where('item_id', $object->id) - ->where('action_type', '=', 'uploaded') + $uploads = self::$map_object_type[$object_type]::withTrashed()->find($id)->uploads() ->with('adminuser'); $offset = ($request->input('offset') > $uploads->count()) ? $uploads->count() : abs($request->input('offset')); @@ -206,7 +202,7 @@ class UploadedFilesController extends Controller Storage::delete(self::$map_storage_path[$object_type].'/'.$log->filename); } // Delete the record of the file - if ($log->delete()) { + if ($log->logUploadDelete($object, $log->filename)) { return response()->json(Helper::formatStandardApiResponse('success', null, trans_choice('general.file_upload_status.delete.success', 1)), 200); } diff --git a/app/Http/Controllers/UploadedFilesController.php b/app/Http/Controllers/UploadedFilesController.php index d3c5bc08a3..8a9f4304ad 100644 --- a/app/Http/Controllers/UploadedFilesController.php +++ b/app/Http/Controllers/UploadedFilesController.php @@ -148,7 +148,7 @@ class UploadedFilesController extends Controller Storage::delete(self::$map_storage_path[$object_type].'/'.$log->filename); } // Delete the record of the file - if ($log->delete()) { + if ($log->logUploadDelete($object, $log->filename)) { return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.success', 1)); } diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 5f0007310c..c62e3031f5 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -50,17 +50,20 @@ class ActionlogsTransformer public function transformActionlog (Actionlog $actionlog, $settings = null) { + $icon = $actionlog->present()->icon(); + if (($actionlog->filename!='') && ($actionlog->action_type!='upload deleted')) { + $icon = Helper::filetype_icon($actionlog->filename); + } + static $custom_fields = false; if ($custom_fields === false) { $custom_fields = CustomField::all(); } - if ($actionlog->filename!='') { - $icon = Helper::filetype_icon($actionlog->filename); - } + // This is necessary since we can't escape special characters within a JSON object if (($actionlog->log_meta) && ($actionlog->log_meta!='')) { diff --git a/app/Models/Actionlog.php b/app/Models/Actionlog.php index 5a1ad2a992..59e7b8244a 100755 --- a/app/Models/Actionlog.php +++ b/app/Models/Actionlog.php @@ -246,19 +246,6 @@ class Actionlog extends SnipeModel } - /** - * Establishes the actionlog -> uploads relationship - * - * @author [A. Gianotto] [] - * @since [v3.0] - * @return \Illuminate\Database\Eloquent\Relations\Relation - */ - public function uploads() - { - return $this->morphTo('item') - ->where('action_type', '=', 'uploaded') - ->withTrashed(); - } /** * Establishes the actionlog -> userlog relationship @@ -456,6 +443,26 @@ class Actionlog extends SnipeModel } + + /** + * @author Godfrey Martinez + * @since [v8.0.4] + * @return \App\Models\Actionlog + */ + public function logUploadDelete($object, $filename) + { + $log = new Actionlog; + $log->item_type = $object instanceof SnipeModel ? get_class($object) : $object; + $log->item_id = $object->id; + $log->created_by = auth()->id(); + $log->target_id = null; + $log->filename = $filename; + $log->created_at = date('Y-m-d H:i:s'); + $log->logaction('upload deleted'); + + return $log; + } + public function uploads_file_url() { diff --git a/app/Models/Traits/HasUploads.php b/app/Models/Traits/HasUploads.php index 400bb84e1f..271da71690 100644 --- a/app/Models/Traits/HasUploads.php +++ b/app/Models/Traits/HasUploads.php @@ -12,7 +12,14 @@ trait HasUploads return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', self::class) ->where('action_type', '=', 'uploaded') - ->whereNotNull('filename'); + ->whereNotNull('filename') + ->whereNotIn('filename', function ($query) { + $query->select('filename') + ->from('action_logs') + ->where('item_type', '=', self::class) + ->where('action_type', '=', 'upload deleted') + ->where('item_id', $this->id); + }); } diff --git a/app/Presenters/ActionlogPresenter.php b/app/Presenters/ActionlogPresenter.php index 4b7aefc87a..7ab022138b 100644 --- a/app/Presenters/ActionlogPresenter.php +++ b/app/Presenters/ActionlogPresenter.php @@ -62,6 +62,10 @@ class ActionlogPresenter extends Presenter return 'fa-solid fa-user-minus'; } + if ($this->action_type == 'upload deleted') { + return 'fa-solid fa-trash'; + } + if ($this->action_type == 'update') { return 'fa-solid fa-user-pen'; } @@ -74,7 +78,7 @@ class ActionlogPresenter extends Presenter return 'fa-solid fa-plus'; } - if ($this->action_type == 'delete') { + if (($this->action_type == 'delete') || ($this->action_type == 'upload deleted')) { return 'fa-solid fa-trash'; } diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index b304bc9725..bfcad0b713 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -611,6 +611,7 @@ return [ 'use_cloned_no_image_help' => 'This item does not have an associated image and instead inherits from the model or category it belongs to. If you would like to use a specific image for this item, you can upload a new one below.', 'footer_credit' => 'Snipe-IT is open source software, made with love by @snipeitapp.com.', 'set_password' => 'Set a Password', + 'upload_deleted' => 'Upload Deleted', // Add form placeholders here 'placeholders' => [