From a55b1c2ca566e95a9ed432408437b4a42e285f0d Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 26 Mar 2025 15:09:42 -0700 Subject: [PATCH 1/7] adds upload deletion logging to Assets --- .../Assets/AssetFilesController.php | 1 + app/Models/Loggable.php | 23 +++++++++++++++++++ resources/lang/en-US/general.php | 1 + 3 files changed, 25 insertions(+) diff --git a/app/Http/Controllers/Assets/AssetFilesController.php b/app/Http/Controllers/Assets/AssetFilesController.php index cf119edddc8c..fb3e05a159fc 100644 --- a/app/Http/Controllers/Assets/AssetFilesController.php +++ b/app/Http/Controllers/Assets/AssetFilesController.php @@ -96,6 +96,7 @@ public function destroy(Asset $asset, $fileId = null) : RedirectResponse if ($log = Actionlog::find($fileId)) { if (Storage::exists($rel_path.'/'.$log->filename)) { + $asset->logUploadDelete($log->filename); Storage::delete($rel_path.'/'.$log->filename); } $log->delete(); diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index 1e4a9120274c..8dfe53beb1a2 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -306,6 +306,29 @@ public function logUpload($filename, $note) $log->filename = $filename; $log->logaction('uploaded'); + return $log; + } + /** + * @author Godfrey Martinez + * @since [v8.0.4] + * @return \App\Models\Actionlog + */ + public function logUploadDelete($filename) + { + $log = new Actionlog; + if (static::class == LicenseSeat::class) { + $log->item_type = License::class; + $log->item_id = $this->license_id; + } else { + $log->item_type = static::class; + $log->item_id = $this->id; + } + $log->created_by = auth()->id(); + $log->target_id = null; + $log->note = $filename; + $log->created_at = date('Y-m-d H:i:s'); + $log->logaction('upload deleted'); + return $log; } } diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index 8366a68216e7..b329f2cf4023 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -317,6 +317,7 @@ 'updating_item' => 'Updating :item', 'upload_filetypes_help' => 'Allowed filetypes are png, gif, jpg, jpeg, doc, docx, pdf, xls, xlsx, txt, lic, xml, zip, rtf and rar. Max upload size allowed is :size.', 'uploaded' => 'Uploaded', + 'upload_deleted' => 'Upload Deleted', 'user' => 'User', 'accepted' => 'accepted', 'declined' => 'declined', From 7e7df92dd61c05595f67a84547f79fd441d41771 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 26 Mar 2025 15:12:30 -0700 Subject: [PATCH 2/7] adds upload deletion logging to Accessories --- app/Http/Controllers/Accessories/AccessoriesFilesController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Accessories/AccessoriesFilesController.php b/app/Http/Controllers/Accessories/AccessoriesFilesController.php index 9dbb16d83aed..7994211175fd 100644 --- a/app/Http/Controllers/Accessories/AccessoriesFilesController.php +++ b/app/Http/Controllers/Accessories/AccessoriesFilesController.php @@ -80,6 +80,7 @@ public function destroy($accessoryId = null, $fileId = null) : RedirectResponse if (Storage::exists('private_uploads/accessories/'.$log->filename)) { try { Storage::delete('private_uploads/accessories/' . $log->filename); + $accessory->logUploadDelete($log->filename); $log->delete(); return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); } catch (\Exception $e) { From aeb9989ec48126215b33372d645ee0db64e53dc5 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 26 Mar 2025 15:15:41 -0700 Subject: [PATCH 3/7] adds upload deletion logging to licenses --- app/Http/Controllers/Licenses/LicenseFilesController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Licenses/LicenseFilesController.php b/app/Http/Controllers/Licenses/LicenseFilesController.php index 6ab3cb7703aa..ae129cb8f17b 100644 --- a/app/Http/Controllers/Licenses/LicenseFilesController.php +++ b/app/Http/Controllers/Licenses/LicenseFilesController.php @@ -75,12 +75,13 @@ public function destroy($licenseId = null, $fileId = null) // Remove the file if one exists if (Storage::exists('licenses/'.$log->filename)) { try { + Storage::delete('licenses/'.$log->filename); } catch (\Exception $e) { Log::debug($e); } } - + $license->logUploadDelete($log->filename); $log->delete(); return redirect()->back() From f99297b0edc46a2e1dec5fb6ee36f7899f36c986 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 26 Mar 2025 15:17:21 -0700 Subject: [PATCH 4/7] adds upload deletion logging to consumables --- app/Http/Controllers/Consumables/ConsumablesFilesController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Consumables/ConsumablesFilesController.php b/app/Http/Controllers/Consumables/ConsumablesFilesController.php index 545b008dc0b1..01cec2a859c2 100644 --- a/app/Http/Controllers/Consumables/ConsumablesFilesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesFilesController.php @@ -86,7 +86,7 @@ public function destroy($consumableId = null, $fileId = null) Log::debug($e); } } - + $consumable->logUploadDelete($log->filename); $log->delete(); return redirect()->back()->withFragment('files') From 695091a79f41ba81784b2c2e529ac38a2c7e72b7 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 26 Mar 2025 15:27:54 -0700 Subject: [PATCH 5/7] removed log deletion of upload record, added filename back to log delete method --- .../Controllers/Accessories/AccessoriesFilesController.php | 2 +- app/Http/Controllers/Assets/AssetFilesController.php | 4 ++-- app/Http/Controllers/Components/ComponentsFilesController.php | 2 +- app/Http/Controllers/Licenses/LicenseFilesController.php | 1 - app/Models/Loggable.php | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Accessories/AccessoriesFilesController.php b/app/Http/Controllers/Accessories/AccessoriesFilesController.php index 7994211175fd..c1d3f12c9fe0 100644 --- a/app/Http/Controllers/Accessories/AccessoriesFilesController.php +++ b/app/Http/Controllers/Accessories/AccessoriesFilesController.php @@ -81,7 +81,7 @@ public function destroy($accessoryId = null, $fileId = null) : RedirectResponse try { Storage::delete('private_uploads/accessories/' . $log->filename); $accessory->logUploadDelete($log->filename); - $log->delete(); + return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); } catch (\Exception $e) { Log::debug($e); diff --git a/app/Http/Controllers/Assets/AssetFilesController.php b/app/Http/Controllers/Assets/AssetFilesController.php index fb3e05a159fc..c9e21419c695 100644 --- a/app/Http/Controllers/Assets/AssetFilesController.php +++ b/app/Http/Controllers/Assets/AssetFilesController.php @@ -96,10 +96,10 @@ public function destroy(Asset $asset, $fileId = null) : RedirectResponse if ($log = Actionlog::find($fileId)) { if (Storage::exists($rel_path.'/'.$log->filename)) { - $asset->logUploadDelete($log->filename); Storage::delete($rel_path.'/'.$log->filename); } - $log->delete(); + $asset->logUploadDelete($log->filename); + return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); } diff --git a/app/Http/Controllers/Components/ComponentsFilesController.php b/app/Http/Controllers/Components/ComponentsFilesController.php index b5e30aa694fd..b8503d078170 100644 --- a/app/Http/Controllers/Components/ComponentsFilesController.php +++ b/app/Http/Controllers/Components/ComponentsFilesController.php @@ -88,7 +88,7 @@ public function destroy($componentId = null, $fileId = null) Log::debug($e); } } - + $component->logUploadDelete($log->filename); $log->delete(); return redirect()->back()->withFragment('files') diff --git a/app/Http/Controllers/Licenses/LicenseFilesController.php b/app/Http/Controllers/Licenses/LicenseFilesController.php index ae129cb8f17b..0227ab7efe55 100644 --- a/app/Http/Controllers/Licenses/LicenseFilesController.php +++ b/app/Http/Controllers/Licenses/LicenseFilesController.php @@ -82,7 +82,6 @@ public function destroy($licenseId = null, $fileId = null) } } $license->logUploadDelete($log->filename); - $log->delete(); return redirect()->back() ->with('success', trans('admin/hardware/message.deletefile.success')); diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index 8dfe53beb1a2..5fd7717ff121 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -326,6 +326,7 @@ public function logUploadDelete($filename) $log->created_by = auth()->id(); $log->target_id = null; $log->note = $filename; + $log->filename = $filename; $log->created_at = date('Y-m-d H:i:s'); $log->logaction('upload deleted'); From 05c3032b2d4d5549acc586f391a379e57e78b20b Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 27 Mar 2025 14:05:49 -0700 Subject: [PATCH 6/7] fixed history and upload relationships --- .../Controllers/Assets/AssetFilesController.php | 2 +- .../Consumables/ConsumablesFilesController.php | 1 - .../Licenses/LicenseFilesController.php | 1 - app/Http/Transformers/ActionlogsTransformer.php | 2 +- app/Models/Accessory.php | 9 ++++++++- app/Models/Asset.php | 15 +++++++++++---- app/Models/Component.php | 9 ++++++++- app/Models/Consumable.php | 9 ++++++++- app/Models/License.php | 9 ++++++++- app/Models/Loggable.php | 1 - 10 files changed, 45 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/Assets/AssetFilesController.php b/app/Http/Controllers/Assets/AssetFilesController.php index c9e21419c695..97a9bd6fa9b4 100644 --- a/app/Http/Controllers/Assets/AssetFilesController.php +++ b/app/Http/Controllers/Assets/AssetFilesController.php @@ -98,7 +98,7 @@ public function destroy(Asset $asset, $fileId = null) : RedirectResponse if (Storage::exists($rel_path.'/'.$log->filename)) { Storage::delete($rel_path.'/'.$log->filename); } - $asset->logUploadDelete($log->filename); + $asset->logUploadDelete($log->filename); return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); } diff --git a/app/Http/Controllers/Consumables/ConsumablesFilesController.php b/app/Http/Controllers/Consumables/ConsumablesFilesController.php index 01cec2a859c2..ff7d40f56e4b 100644 --- a/app/Http/Controllers/Consumables/ConsumablesFilesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesFilesController.php @@ -87,7 +87,6 @@ public function destroy($consumableId = null, $fileId = null) } } $consumable->logUploadDelete($log->filename); - $log->delete(); return redirect()->back()->withFragment('files') ->with('success', trans('admin/hardware/message.deletefile.success')); diff --git a/app/Http/Controllers/Licenses/LicenseFilesController.php b/app/Http/Controllers/Licenses/LicenseFilesController.php index 0227ab7efe55..03c252fe5b76 100644 --- a/app/Http/Controllers/Licenses/LicenseFilesController.php +++ b/app/Http/Controllers/Licenses/LicenseFilesController.php @@ -75,7 +75,6 @@ public function destroy($licenseId = null, $fileId = null) // Remove the file if one exists if (Storage::exists('licenses/'.$log->filename)) { try { - Storage::delete('licenses/'.$log->filename); } catch (\Exception $e) { Log::debug($e); diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 702ea123d8f2..8b0119199a54 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -57,7 +57,7 @@ public function transformActionlog (Actionlog $actionlog, $settings = null) } if ($actionlog->filename!='') { - $icon = Helper::filetype_icon($actionlog->filename); + $icon = $actionlog->action_type === 'upload deleted' ? 'fas fa-trash' : Helper::filetype_icon($actionlog->filename); } // This is necessary since we can't escape special characters within a JSON object diff --git a/app/Models/Accessory.php b/app/Models/Accessory.php index fc1bb36ab40d..9f38faaefd50 100755 --- a/app/Models/Accessory.php +++ b/app/Models/Accessory.php @@ -111,10 +111,17 @@ class Accessory extends SnipeModel */ public function uploads() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id') + return $this->hasMany('\App\Models\Actionlog', 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->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); + }) ->orderBy('created_at', 'desc'); } diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 4685617b1dae..6691b239d20d 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -478,10 +478,17 @@ public function get_depreciation() public function uploads() { return $this->hasMany('\App\Models\Actionlog', 'item_id') - ->where('item_type', '=', Asset::class) - ->where('action_type', '=', 'uploaded') - ->whereNotNull('filename') - ->orderBy('created_at', 'desc'); + ->where('item_type', '=', self::class) + ->where('action_type', '=', 'uploaded') + ->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); + }) + ->orderBy('created_at', 'desc'); } /** diff --git a/app/Models/Component.php b/app/Models/Component.php index d9277d7da7d1..371fb89a7d1e 100644 --- a/app/Models/Component.php +++ b/app/Models/Component.php @@ -121,10 +121,17 @@ public function isDeletable() */ public function uploads() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id') + return $this->hasMany('\App\Models\Actionlog', 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->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); + }) ->orderBy('created_at', 'desc'); } diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php index 30161e84296a..bf33a1b3c5e4 100644 --- a/app/Models/Consumable.php +++ b/app/Models/Consumable.php @@ -118,10 +118,17 @@ class Consumable extends SnipeModel */ public function uploads() { - return $this->hasMany(Actionlog::class, 'item_id') + return $this->hasMany('\App\Models\Actionlog', 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->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); + }) ->orderBy('created_at', 'desc'); } diff --git a/app/Models/License.php b/app/Models/License.php index 0997c1e57b99..12d8d3cdad55 100755 --- a/app/Models/License.php +++ b/app/Models/License.php @@ -416,10 +416,17 @@ public function assetlog() */ public function uploads() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id') + return $this->hasMany('\App\Models\Actionlog', 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->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); + }) ->orderBy('created_at', 'desc'); } diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index 5fd7717ff121..f0e14619bf71 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -325,7 +325,6 @@ public function logUploadDelete($filename) } $log->created_by = auth()->id(); $log->target_id = null; - $log->note = $filename; $log->filename = $filename; $log->created_at = date('Y-m-d H:i:s'); $log->logaction('upload deleted'); From b29e1888af2718d14f061c7ffbff00557b48f980 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 2 Apr 2025 11:12:27 -0700 Subject: [PATCH 7/7] changed relation from string to ::class format --- app/Models/Accessory.php | 2 +- app/Models/Asset.php | 2 +- app/Models/Component.php | 4 ++-- app/Models/Consumable.php | 2 +- app/Models/License.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Models/Accessory.php b/app/Models/Accessory.php index 9f38faaefd50..c718db0ccc35 100755 --- a/app/Models/Accessory.php +++ b/app/Models/Accessory.php @@ -111,7 +111,7 @@ class Accessory extends SnipeModel */ public function uploads() { - return $this->hasMany('\App\Models\Actionlog', 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename') diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 6691b239d20d..103a07164b23 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -477,7 +477,7 @@ public function get_depreciation() */ public function uploads() { - return $this->hasMany('\App\Models\Actionlog', 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename') diff --git a/app/Models/Component.php b/app/Models/Component.php index 371fb89a7d1e..c419f76be5cb 100644 --- a/app/Models/Component.php +++ b/app/Models/Component.php @@ -121,7 +121,7 @@ public function isDeletable() */ public function uploads() { - return $this->hasMany('\App\Models\Actionlog', 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename') @@ -232,7 +232,7 @@ public function manufacturer() */ public function assetlog() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id')->where('item_type', self::class)->orderBy('created_at', 'desc')->withTrashed(); + return $this->hasMany(Actionlog::class, 'item_id')->where('item_type', self::class)->orderBy('created_at', 'desc')->withTrashed(); } /** diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php index bf33a1b3c5e4..91446dd0b7f0 100644 --- a/app/Models/Consumable.php +++ b/app/Models/Consumable.php @@ -118,7 +118,7 @@ class Consumable extends SnipeModel */ public function uploads() { - return $this->hasMany('\App\Models\Actionlog', 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename') diff --git a/app/Models/License.php b/app/Models/License.php index 12d8d3cdad55..36f515186fe6 100755 --- a/app/Models/License.php +++ b/app/Models/License.php @@ -416,7 +416,7 @@ public function assetlog() */ public function uploads() { - return $this->hasMany('\App\Models\Actionlog', 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename')