From b5ec9e080dd692178f32a4be58cda0fb0dbaf579 Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 8 Jun 2026 16:19:21 +0100 Subject: [PATCH] QR Codes: Added QR codes for non-assets --- .../Controllers/Assets/AssetsController.php | 2 +- app/Http/Controllers/QrCodeController.php | 66 +++++++++++++++++++ .../Transformers/AccessoriesTransformer.php | 1 + .../Transformers/AssetModelsTransformer.php | 1 + app/Http/Transformers/AssetsTransformer.php | 1 + .../Transformers/CompaniesTransformer.php | 1 + .../Transformers/ComponentsTransformer.php | 1 + .../Transformers/ConsumablesTransformer.php | 1 + app/Http/Transformers/LicensesTransformer.php | 1 + .../Transformers/LocationsTransformer.php | 1 + app/Http/Transformers/UsersTransformer.php | 2 +- app/Models/Setting.php | 5 ++ resources/views/accessories/view.blade.php | 2 +- .../views/blade/info-panel/index.blade.php | 7 ++ resources/views/companies/view.blade.php | 2 +- resources/views/components/view.blade.php | 2 +- resources/views/consumables/view.blade.php | 2 +- resources/views/hardware/labels.blade.php | 4 +- resources/views/hardware/view.blade.php | 5 +- resources/views/licenses/view.blade.php | 2 +- resources/views/locations/view.blade.php | 2 +- resources/views/models/view.blade.php | 2 +- resources/views/users/view.blade.php | 5 ++ routes/web.php | 9 +++ routes/web/hardware.php | 4 -- 25 files changed, 114 insertions(+), 17 deletions(-) create mode 100644 app/Http/Controllers/QrCodeController.php diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index fbeb21898a..c6962e51b8 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -358,7 +358,7 @@ class AssetsController extends Controller $qr_code = (object) [ 'display' => $settings->qr_code == '1', - 'url' => route('qr_code/hardware', $asset), + 'url' => route('qr_code/common', ['object_type' => 'hardware', 'id' => $asset->id]), ]; $total_maintenance_cost = $asset->maintenances?->sum('cost'); diff --git a/app/Http/Controllers/QrCodeController.php b/app/Http/Controllers/QrCodeController.php new file mode 100644 index 0000000000..4acaad619f --- /dev/null +++ b/app/Http/Controllers/QrCodeController.php @@ -0,0 +1,66 @@ + 'accessories.show', + 'assets' => 'hardware.show', + 'companies' => 'companies.show', + 'components' => 'components.show', + 'consumables' => 'consumables.show', + 'hardware' => 'hardware.show', + 'licenses' => 'licenses.show', + 'locations' => 'locations.show', + 'models' => 'models.show', + 'users' => 'users.show', + ]; + + public function show($object_type, $id): Response|BinaryFileResponse|string|bool + { + $settings = Setting::getSettings(); + + if ($settings->label2_2d_type === 'none') { + return false; + } + + if (! array_key_exists($object_type, self::$map_show_route)) { + return $object_type.' is not a valid type.'; + } + + $object = self::$map_object_type[$object_type]::withTrashed()->find($id); + + if (! $object) { + return 'That item is invalid'; + } + + $this->authorize('view', $object); + + $size = Helper::barcodeDimensions($settings->label2_2d_type); + $qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($object_type).'-'.str_slug($id).'.png'; + + if (file_exists($qr_file)) { + return response()->file($qr_file, ['Content-type' => 'image/png']); + } + + $barcode = new Barcode; + $barcode_obj = $barcode->getBarcodeObj( + $settings->label2_2d_type, + route(self::$map_show_route[$object_type], $id), + $size['height'], + $size['width'], + 'black', + [-2, -2, -2, -2] + ); + file_put_contents($qr_file, $barcode_obj->getPngData()); + + return response($barcode_obj->getPngData())->header('Content-type', 'image/png'); + } +} diff --git a/app/Http/Transformers/AccessoriesTransformer.php b/app/Http/Transformers/AccessoriesTransformer.php index 5ff7b96e33..13f0cba8e7 100644 --- a/app/Http/Transformers/AccessoriesTransformer.php +++ b/app/Http/Transformers/AccessoriesTransformer.php @@ -26,6 +26,7 @@ class AccessoriesTransformer 'id' => $accessory->id, 'name' => e($accessory->name), 'image' => ($accessory->image) ? Storage::disk('public')->url('accessories/'.e($accessory->image)) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'accessories', 'id' => $accessory->id]), 'company' => ($accessory->company) ? [ 'id' => $accessory->company->id, 'name' => e($accessory->company->name), diff --git a/app/Http/Transformers/AssetModelsTransformer.php b/app/Http/Transformers/AssetModelsTransformer.php index 62b3570c93..f900bca709 100644 --- a/app/Http/Transformers/AssetModelsTransformer.php +++ b/app/Http/Transformers/AssetModelsTransformer.php @@ -48,6 +48,7 @@ class AssetModelsTransformer 'tag_color' => ($assetmodel->manufacturer->tag_color) ? e($assetmodel->manufacturer->tag_color) : null, ] : null, 'image' => ($assetmodel->image != '') ? Storage::disk('public')->url('models/'.e($assetmodel->image)) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'models', 'id' => $assetmodel->id]), 'model_number' => ($assetmodel->model_number ? e($assetmodel->model_number) : null), 'min_amt' => ($assetmodel->min_amt) ? (int) $assetmodel->min_amt : null, diff --git a/app/Http/Transformers/AssetsTransformer.php b/app/Http/Transformers/AssetsTransformer.php index a62df14c04..b8dc9d4a14 100644 --- a/app/Http/Transformers/AssetsTransformer.php +++ b/app/Http/Transformers/AssetsTransformer.php @@ -98,6 +98,7 @@ class AssetsTransformer 'tag_color' => ($asset->defaultLoc->tag_color) ? e($asset->defaultLoc->tag_color) : null, ] : null, 'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'hardware', 'id' => $asset->id]), 'qr' => ($setting->qr_code == '1') ? Storage::disk('public')->url('barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png') : null, 'alt_barcode' => ($setting->alt_barcode_enabled == '1') ? Storage::disk('public')->url('barcodes/'.str_slug($setting->alt_barcode).'-'.str_slug($asset->asset_tag).'.png') : null, 'assigned_to' => $this->transformAssignedTo($asset), diff --git a/app/Http/Transformers/CompaniesTransformer.php b/app/Http/Transformers/CompaniesTransformer.php index bd18474533..af60ceab49 100644 --- a/app/Http/Transformers/CompaniesTransformer.php +++ b/app/Http/Transformers/CompaniesTransformer.php @@ -30,6 +30,7 @@ class CompaniesTransformer 'fax' => ($company->fax != '') ? e($company->fax) : null, 'email' => ($company->email != '') ? e($company->email) : null, 'image' => ($company->image) ? Storage::disk('public')->url('companies/'.e($company->image)) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'companies', 'id' => $company->id]), 'assets_count' => (int) $company->assets_count, 'licenses_count' => (int) $company->licenses_count, 'accessories_count' => (int) $company->accessories_count, diff --git a/app/Http/Transformers/ComponentsTransformer.php b/app/Http/Transformers/ComponentsTransformer.php index 7a281d796b..ad07408a8c 100644 --- a/app/Http/Transformers/ComponentsTransformer.php +++ b/app/Http/Transformers/ComponentsTransformer.php @@ -26,6 +26,7 @@ class ComponentsTransformer 'id' => (int) $component->id, 'name' => e($component->name), 'image' => ($component->image) ? Storage::disk('public')->url('components/'.e($component->image)) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'components', 'id' => $component->id]), 'serial' => ($component->serial) ? e($component->serial) : null, 'location' => ($component->location) ? [ 'id' => (int) $component->location->id, diff --git a/app/Http/Transformers/ConsumablesTransformer.php b/app/Http/Transformers/ConsumablesTransformer.php index bfda390b12..5297c7d587 100644 --- a/app/Http/Transformers/ConsumablesTransformer.php +++ b/app/Http/Transformers/ConsumablesTransformer.php @@ -25,6 +25,7 @@ class ConsumablesTransformer 'id' => (int) $consumable->id, 'name' => e($consumable->name), 'image' => ($consumable->getImageUrl()) ? ($consumable->getImageUrl()) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'consumables', 'id' => $consumable->id]), 'category' => ($consumable->category) ? [ 'id' => $consumable->category->id, 'name' => e($consumable->category->name), diff --git a/app/Http/Transformers/LicensesTransformer.php b/app/Http/Transformers/LicensesTransformer.php index 9243f1b7db..133715c3bb 100644 --- a/app/Http/Transformers/LicensesTransformer.php +++ b/app/Http/Transformers/LicensesTransformer.php @@ -24,6 +24,7 @@ class LicensesTransformer $array = [ 'id' => (int) $license->id, 'name' => e($license->name), + 'qr_code_url' => route('qr_code/common', ['object_type' => 'licenses', 'id' => $license->id]), 'company' => ($license->company) ? ['id' => (int) $license->company->id, 'name' => e($license->company->name)] : null, 'manufacturer' => ($license->manufacturer) ? [ 'id' => (int) $license->manufacturer->id, diff --git a/app/Http/Transformers/LocationsTransformer.php b/app/Http/Transformers/LocationsTransformer.php index 8802ca7be5..b61fbe9cbc 100644 --- a/app/Http/Transformers/LocationsTransformer.php +++ b/app/Http/Transformers/LocationsTransformer.php @@ -39,6 +39,7 @@ class LocationsTransformer 'id' => (int) $location->id, 'name' => e($location->name), 'image' => ($location->image) ? Storage::disk('public')->url('locations/'.e($location->image)) : null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'locations', 'id' => $location->id]), 'address' => ($location->address) ? e($location->address) : null, 'address2' => ($location->address2) ? e($location->address2) : null, 'city' => ($location->city) ? e($location->city) : null, diff --git a/app/Http/Transformers/UsersTransformer.php b/app/Http/Transformers/UsersTransformer.php index bc4e828d41..41c9c0c5b4 100644 --- a/app/Http/Transformers/UsersTransformer.php +++ b/app/Http/Transformers/UsersTransformer.php @@ -21,7 +21,6 @@ class UsersTransformer public function transformUser(User $user) { - $role = null; if ($user->isSuperUser()) { $role = 'superadmin'; @@ -31,6 +30,7 @@ class UsersTransformer $array = [ 'id' => (int) $user->id, 'avatar' => e($user->present()->gravatar) ?? null, + 'qr_code_url' => route('qr_code/common', ['object_type' => 'users', 'id' => $user->id]), 'name' => e($user->getFullNameAttribute()) ?? null, 'first_name' => e($user->first_name) ?? null, 'last_name' => e($user->last_name) ?? null, diff --git a/app/Models/Setting.php b/app/Models/Setting.php index a0f6fe7842..bc5d1e856e 100755 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -216,6 +216,11 @@ class Setting extends Model return $custom_css; } + public function isQrEnabled(): bool + { + return $this->qr_code == '1' || $this->label2_2d_type !== 'none'; + } + /** * Converts bytes into human readable file size. * diff --git a/resources/views/accessories/view.blade.php b/resources/views/accessories/view.blade.php index de864994e4..ed2f879275 100644 --- a/resources/views/accessories/view.blade.php +++ b/resources/views/accessories/view.blade.php @@ -66,7 +66,7 @@ - + diff --git a/resources/views/blade/info-panel/index.blade.php b/resources/views/blade/info-panel/index.blade.php index ae004deb8c..e6f7923207 100644 --- a/resources/views/blade/info-panel/index.blade.php +++ b/resources/views/blade/info-panel/index.blade.php @@ -1,6 +1,7 @@ @props([ 'infoPanelObj' => null, 'img_path' => null, + 'qr_code_url' => null, 'snipeSettings' => \App\Models\Setting::getSettings() ]) @@ -589,6 +590,12 @@ {{ $after_list }} @endif + @if ($qr_code_url && $snipeSettings->isQrEnabled()) +
+ QR code for {{ $infoPanelObj->name }} +
+ @endif + diff --git a/resources/views/companies/view.blade.php b/resources/views/companies/view.blade.php index 625b7d9add..7ef109c729 100644 --- a/resources/views/companies/view.blade.php +++ b/resources/views/companies/view.blade.php @@ -75,7 +75,7 @@
- + diff --git a/resources/views/components/view.blade.php b/resources/views/components/view.blade.php index b061ac39b8..9de3a08a6b 100644 --- a/resources/views/components/view.blade.php +++ b/resources/views/components/view.blade.php @@ -61,7 +61,7 @@ - + diff --git a/resources/views/consumables/view.blade.php b/resources/views/consumables/view.blade.php index 2bceb13735..8f4224f0c7 100644 --- a/resources/views/consumables/view.blade.php +++ b/resources/views/consumables/view.blade.php @@ -62,7 +62,7 @@ - + diff --git a/resources/views/hardware/labels.blade.php b/resources/views/hardware/labels.blade.php index 0d675d3beb..654825a8fa 100644 --- a/resources/views/hardware/labels.blade.php +++ b/resources/views/hardware/labels.blade.php @@ -112,7 +112,7 @@ $qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->label2_1d_type!= @if ($settings->qr_code=='1')
- +
@endif @@ -166,7 +166,7 @@ $qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->label2_1d_type!= - @if (($count % $settings->labels_per_page == 0) && $count!=count($assets)) + @if ($settings->labels_per_page > 0 && ($count % $settings->labels_per_page == 0) && $count != count($assets))
 
@endif diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index 479a0f234a..e850ab3416 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -318,12 +318,13 @@ - @if (($snipeSettings->qr_code=='1') || $snipeSettings->label2_2d_type!='none') + @if ($snipeSettings->isQrEnabled())
- QR code for {{ $asset->getDisplayNameAttribute() }} + QR code for {{ $asset->getDisplayNameAttribute() }}
@endif +
diff --git a/resources/views/licenses/view.blade.php b/resources/views/licenses/view.blade.php index f82e4dd24b..15ca47d577 100755 --- a/resources/views/licenses/view.blade.php +++ b/resources/views/licenses/view.blade.php @@ -104,7 +104,7 @@ - + diff --git a/resources/views/locations/view.blade.php b/resources/views/locations/view.blade.php index 4f65c4adf4..81e5ae3f00 100644 --- a/resources/views/locations/view.blade.php +++ b/resources/views/locations/view.blade.php @@ -216,7 +216,7 @@ - + diff --git a/resources/views/models/view.blade.php b/resources/views/models/view.blade.php index 83fdb6af64..017d945fea 100755 --- a/resources/views/models/view.blade.php +++ b/resources/views/models/view.blade.php @@ -54,7 +54,7 @@ - + diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index 2512451684..d64cb8cac5 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -303,6 +303,11 @@ @endif + @if ($snipeSettings->isQrEnabled()) +
+ QR code for {{ $user->display_name }} +
+ @endif
diff --git a/routes/web.php b/routes/web.php index f2f9be664e..4f69d954a7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -22,6 +22,7 @@ use App\Http\Controllers\ManufacturersController; use App\Http\Controllers\ModalController; use App\Http\Controllers\NotesController; use App\Http\Controllers\ProfileController; +use App\Http\Controllers\QrCodeController; use App\Http\Controllers\ReportsController; use App\Http\Controllers\ReportTemplatesController; use App\Http\Controllers\SettingsController; @@ -697,6 +698,14 @@ Route::group(['middleware' => 'web'], function () { [LoginController::class, 'logout'] )->name('logout.post'); + /** + * QR Code routes + */ + Route::get('{object_type}/{id}/qr_code', + [QrCodeController::class, 'show'] + )->name('qr_code/common') + ->where(['object_type' => 'accessories|assets|hardware|licenses|locations|models|companies|components|consumables|users']); + /** * Uploaded files API routes */ diff --git a/routes/web/hardware.php b/routes/web/hardware.php index a9bffd6b19..21c2dc27b1 100644 --- a/routes/web/hardware.php +++ b/routes/web/hardware.php @@ -123,10 +123,6 @@ Route::group( return redirect()->route('hardware.show', $assetId); }); - Route::get('{asset}/qr_code', - [AssetsController::class, 'getQrCode'] - )->name('qr_code/hardware')->withTrashed(); - Route::get('{asset}/barcode', [AssetsController::class, 'getBarCode'] )->name('barcode/hardware')->withTrashed();