From e8404c87204d3b0438ff2a67b05b5fa318429883 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 21 Apr 2025 14:41:52 +0100 Subject: [PATCH 1/5] Moved location routes Signed-off-by: snipe --- .../Controllers/LocationsFilesController.php | 112 ++++++++++++++++++ routes/web.php | 41 ------- routes/web/locations.php | 56 +++++++++ 3 files changed, 168 insertions(+), 41 deletions(-) create mode 100644 app/Http/Controllers/LocationsFilesController.php create mode 100644 routes/web/locations.php diff --git a/app/Http/Controllers/LocationsFilesController.php b/app/Http/Controllers/LocationsFilesController.php new file mode 100644 index 000000000..41425124c --- /dev/null +++ b/app/Http/Controllers/LocationsFilesController.php @@ -0,0 +1,112 @@ +] + */ + public function store(UploadFileRequest $request, Location $location) : RedirectResponse + { + + $this->authorize('update', $location); + + if ($request->hasFile('file')) { + if (! Storage::exists('private_uploads/locations')) { + Storage::makeDirectory('private_uploads/locations', 775); + } + + foreach ($request->file('file') as $file) { + + $file_name = $request->handleFile('private_uploads/locations/','model-'.$location->id,$file); + $location->logUpload($file_name, $request->get('notes')); + } + + return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success')); + } + + return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles')); + } + + /** + * Check for permissions and display the file. + * + * @author [A. Gianotto] [] + * @param int $modelId + * @param int $fileId + * @since [v1.0] + */ + public function show(Location $location, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse + { + + $this->authorize('view', $location); + + if (! $log = Actionlog::find($fileId)) { + return redirect()->back()->withFragment('files')->with('error', 'No matching file record'); + } + + $file = 'private_uploads/locations/'.$log->filename; + + if (! Storage::exists($file)) { + return redirect()->back()->withFragment('files')->with('error', 'No matching file on server'); + } + + if (request('inline') == 'true') { + + $headers = [ + 'Content-Disposition' => 'inline', + ]; + + return Storage::download($file, $log->filename, $headers); + } + + return StorageHelper::downloader($file); + } + + /** + * Delete the associated file + * + * @author [A. Gianotto] [] + * @param int $modelId + * @param int $fileId + * @since [v1.0] + */ + public function destroy(Location $location, $fileId = null) : RedirectResponse + { + $rel_path = 'private_uploads/locations'; + $this->authorize('update', $location); + $log = Actionlog::find($fileId); + + if ($log) { + + // This should be moved to purge +// if (Storage::exists($rel_path.'/'.$log->filename)) { +// Storage::delete($rel_path.'/'.$log->filename); +// } + $log->delete(); + + return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); + } + + return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success')); + + } +} diff --git a/routes/web.php b/routes/web.php index 14326f160..9d7b7af88 100644 --- a/routes/web.php +++ b/routes/web.php @@ -52,47 +52,6 @@ Route::group(['middleware' => 'auth'], function () { [LabelsController::class, 'show'] )->where('labelName', '.*')->name('labels.show'); - /* - * Locations - */ - Route::group(['prefix' => 'locations', 'middleware' => ['auth']], function () { - - Route::post( - 'bulkdelete', - [LocationsController::class, 'postBulkDelete'] - )->name('locations.bulkdelete.show'); - - Route::post( - 'bulkedit', - [LocationsController::class, 'postBulkDeleteStore'] - )->name('locations.bulkdelete.store'); - - Route::post( - '{location}/restore', - [LocationsController::class, 'postRestore'] - )->name('locations.restore'); - - - Route::get('{locationId}/clone', - [LocationsController::class, 'getClone'] - )->name('clone/location'); - - Route::get( - '{locationId}/printassigned', - [LocationsController::class, 'print_assigned'] - )->name('locations.print_assigned'); - - Route::get( - '{locationId}/printallassigned', - [LocationsController::class, 'print_all_assigned'] - )->name('locations.print_all_assigned'); - - }); - - Route::resource('locations', LocationsController::class, [ - 'parameters' => ['location' => 'location_id'], - ]); - /* * Manufacturers diff --git a/routes/web/locations.php b/routes/web/locations.php new file mode 100644 index 000000000..ff2218f5b --- /dev/null +++ b/routes/web/locations.php @@ -0,0 +1,56 @@ + 'locations', 'middleware' => ['auth']], function () { + + Route::post('{location}/upload', + [LocationsFilesController::class, 'store'] + )->name('upload/locations')->withTrashed(); + + Route::get('{location}/showfile/{fileId}/{download?}', + [LocationsFilesController::class, 'show'] + )->name('show/locationsfile')->withTrashed(); + + Route::delete('{location}/showfile/{fileId}/delete', + [LocationsFilesController::class, 'destroy'] + )->name('delete/locationsfile')->withTrashed(); + + + Route::post( + 'bulkdelete', + [LocationsController::class, 'postBulkDelete'] + )->name('locations.bulkdelete.show'); + + Route::post( + 'bulkedit', + [LocationsController::class, 'postBulkDeleteStore'] + )->name('locations.bulkdelete.store'); + + Route::post( + '{location}/restore', + [LocationsController::class, 'postRestore'] + )->name('locations.restore'); + + + Route::get('{locationId}/clone', + [LocationsController::class, 'getClone'] + )->name('clone/location'); + + Route::get( + '{locationId}/printassigned', + [LocationsController::class, 'print_assigned'] + )->name('locations.print_assigned'); + + Route::get( + '{locationId}/printallassigned', + [LocationsController::class, 'print_all_assigned'] + )->name('locations.print_all_assigned'); + +}); + +Route::resource('locations', LocationsController::class, [ + 'middleware' => ['auth'], +])->withTrashed(); From 9d313eb2d950d0b003197543697deada90e96c69 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 21 Apr 2025 14:42:02 +0100 Subject: [PATCH 2/5] Added locations dir Signed-off-by: snipe --- storage/private_uploads/locations/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 storage/private_uploads/locations/.gitignore diff --git a/storage/private_uploads/locations/.gitignore b/storage/private_uploads/locations/.gitignore new file mode 100644 index 000000000..c96a04f00 --- /dev/null +++ b/storage/private_uploads/locations/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file From 00092a079fcf658e04864d0b996d888f440d1990 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 21 Apr 2025 14:42:10 +0100 Subject: [PATCH 3/5] Added uploads method Signed-off-by: snipe --- app/Models/Location.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/Models/Location.php b/app/Models/Location.php index 69c79cfae..9b1ed02f4 100755 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -20,6 +20,7 @@ class Location extends SnipeModel { use HasFactory; use CompanyableTrait; + use Loggable; protected $presenter = \App\Presenters\LocationPresenter::class; use Presentable; @@ -288,6 +289,23 @@ class Location extends SnipeModel return $this->attributes['ldap_ou'] = empty($ldap_ou) ? null : $ldap_ou; } + /** + * Get uploads for this location + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function uploads() + { + return $this->hasMany('\App\Models\Actionlog', 'item_id') + ->where('item_type', '=', Location::class) + ->where('action_type', '=', 'uploaded') + ->whereNotNull('filename') + ->orderBy('created_at', 'desc'); + } + + /** * Query builder scope to order on parent * From 2ebe1ebc690de8de3284b690365a2bea151c5015 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 21 Apr 2025 14:42:58 +0100 Subject: [PATCH 4/5] Load location route files Signed-off-by: snipe --- app/Providers/RouteServiceProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index d5b10bde3..276aaf1e4 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -45,6 +45,7 @@ class RouteServiceProvider extends ServiceProvider require base_path('routes/web/models.php'); require base_path('routes/web/accessories.php'); require base_path('routes/web/licenses.php'); + require base_path('routes/web/locations.php'); require base_path('routes/web/consumables.php'); require base_path('routes/web/fields.php'); require base_path('routes/web/components.php'); From beb5560dcecdbc1c69950278c59a28eaac353515 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 21 Apr 2025 14:43:04 +0100 Subject: [PATCH 5/5] Added files tab Signed-off-by: snipe --- resources/views/locations/view.blade.php | 46 +++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/resources/views/locations/view.blade.php b/resources/views/locations/view.blade.php index 3d3b6a524..2f7cb075b 100644 --- a/resources/views/locations/view.blade.php +++ b/resources/views/locations/view.blade.php @@ -144,7 +144,22 @@ @endif @endcan - + + @if ($location->uploads->count() > 0 ) +
  • + + + + + +
  • + @endif +
  • @@ -153,6 +168,15 @@
  • + + @can('update', $location) +
  • + + + {{ trans('button.upload') }} + +
  • + @endcan @@ -375,6 +399,22 @@ +
    + +
    +
    + + + +
    +
    + +
    +

    {{ trans('general.history') }}

    @@ -550,6 +590,10 @@ @section('moar_scripts') + @can('update', Location::class) + @include ('modals.upload-file', ['item_type' => 'locations', 'item_id' => $location->id]) + @endcan +