diff --git a/controllers/Api/FilesApiController.php b/controllers/Api/FilesApiController.php index 41724692..5d2c8550 100644 --- a/controllers/Api/FilesApiController.php +++ b/controllers/Api/FilesApiController.php @@ -47,45 +47,25 @@ class FilesApiController extends BaseApiController throw new \Exception('Invalid file group'); } - $fileName = $this->CheckFileName($args['fileName']); - $filePath = $this->GetFilePath($args['group'], $fileName, $request->getQueryParams()); - - if (file_exists($filePath)) + if (str_contains($args['fileName'], '_')) { - $response = $response->withHeader('Cache-Control', 'max-age=2592000'); - $response = $response->withHeader('Content-Type', mime_content_type($filePath)); - $response = $response->withHeader('Content-Disposition', 'inline; filename="' . $fileName . '"'); - return $response->withBody(new Stream(fopen($filePath, 'rb'))); + $fileInfo = explode('_', $args['fileName']); + $fileName = $this->CheckFileName($fileInfo[0]); + $fileNameOutput = $this->CheckFileName($fileInfo[1]); + $filePath = $this->GetFilePath($args['group'], $fileName, $request->getQueryParams()); } else { - throw new HttpNotFoundException($request, 'File not found'); + $fileName = $this->CheckFileName($args['fileName']); + $fileNameOutput = $fileName; + $filePath = $this->GetFilePath($args['group'], $fileName, $request->getQueryParams()); } - } - catch (\Exception $ex) - { - throw new HttpNotFoundException($request, $ex->getMessage(), $ex); - } - } - - public function ShowFile(Request $request, Response $response, array $args) - { - try - { - if (!in_array($args['group'], $this->GetOpenApispec()->components->schemas->FileGroups->enum)) - { - throw new \Exception('Invalid file group'); - } - - $fileInfo = explode('_', $args['fileName']); - $fileName = $this->CheckFileName($fileInfo[1]); - $filePath = $this->GetFilePath($args['group'], base64_decode($fileInfo[0]), $request->getQueryParams()); if (file_exists($filePath)) { $response = $response->withHeader('Cache-Control', 'max-age=2592000'); $response = $response->withHeader('Content-Type', mime_content_type($filePath)); - $response = $response->withHeader('Content-Disposition', 'inline; filename="' . $fileName . '"'); + $response = $response->withHeader('Content-Disposition', 'inline; filename="' . $fileNameOutput . '"'); return $response->withBody(new Stream(fopen($filePath, 'rb'))); } else diff --git a/public/viewjs/components/userfieldsform.js b/public/viewjs/components/userfieldsform.js index 6e208b48..8ff78f40 100644 --- a/public/viewjs/components/userfieldsform.js +++ b/public/viewjs/components/userfieldsform.js @@ -1,6 +1,6 @@ Grocy.Components.UserfieldsForm = {}; -Grocy.Components.UserfieldsForm.Save = function(success, error) +Grocy.Components.UserfieldsForm.Save = function (success, error) { if (!$("#userfields-form").length) { @@ -24,7 +24,7 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) return; } - editedUserfieldInputs.each(function(index, item) + editedUserfieldInputs.each(function (index, item) { var jsonData = {}; var input = $(this); @@ -68,22 +68,22 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) } Grocy.Api.Put('userfields/' + $("#userfields-form").data("entity") + '/' + Grocy.EditObjectId, jsonData, - function(result) + function (result) { if (typeof newFile !== 'undefined' && typeof oldFile !== 'undefined') // Delete and Upload { Grocy.Api.DeleteFile(oldFile, 'userfiles', - function(result) + function (result) { Grocy.Api.UploadFile(input[0].files[0], 'userfiles', newFile, - function(result2) + function (result2) { if (success && index === editedUserfieldInputs.length - 1) // Last item { success(); } }, - function(xhr) + function (xhr) { Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); if (error && index === editedUserfieldInputs.length - 1) // Last item @@ -93,7 +93,7 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) } ); }, - function(xhr) + function (xhr) { Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); if (error && index === editedUserfieldInputs.length - 1) // Last item @@ -106,14 +106,14 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) else if (typeof newFile !== 'undefined') // Upload only { Grocy.Api.UploadFile(input[0].files[0], 'userfiles', newFile, - function(result2) + function (result2) { if (success && index === editedUserfieldInputs.length - 1) // Last item { success(); } }, - function(xhr) + function (xhr) { Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); if (error && index === editedUserfieldInputs.length - 1) // Last item @@ -126,14 +126,14 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) else if (typeof oldFile !== 'undefined') // Delete only { Grocy.Api.DeleteFile(oldFile, 'userfiles', - function(result) + function (result) { if (success && index === editedUserfieldInputs.length - 1) // Last item { success(); } }, - function(xhr) + function (xhr) { Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response); if (error && index === editedUserfieldInputs.length - 1) // Last item @@ -151,7 +151,7 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) } } }, - function(xhr) + function (xhr) { if (error && index === editedUserfieldInputs.length - 1) // Last item { @@ -162,7 +162,7 @@ Grocy.Components.UserfieldsForm.Save = function(success, error) }); } -Grocy.Components.UserfieldsForm.Load = function() +Grocy.Components.UserfieldsForm.Load = function () { if (!$("#userfields-form").length) { @@ -174,9 +174,9 @@ Grocy.Components.UserfieldsForm.Load = function() // Init fields by configured default values Grocy.Api.Get("objects/userfields?query[]=entity=" + $("#userfields-form").data("entity"), - function(result) + function (result) { - $.each(result, function(key, userfield) + $.each(result, function (key, userfield) { var input = $(".userfield-input[data-userfield-name='" + userfield.name + "']"); @@ -191,19 +191,19 @@ Grocy.Components.UserfieldsForm.Load = function() else if (userfield.type == "checkbox" && userfield.input_required == 1) { input.prop("indeterminate", true); - input.on("change", function() + input.on("change", function () { input.removeAttr("required"); }); } }); - $("form").each(function() + $("form").each(function () { Grocy.FrontendHelpers.ValidateForm(this.id); }); }, - function(xhr) + function (xhr) { console.error(xhr); } @@ -214,9 +214,9 @@ Grocy.Components.UserfieldsForm.Load = function() // Load object field values Grocy.Api.Get('userfields/' + $("#userfields-form").data("entity") + '/' + Grocy.EditObjectId, - function(result) + function (result) { - $.each(result, function(key, value) + $.each(result, function (key, value) { var input = $(".userfield-input[data-userfield-name='" + key + "']"); @@ -248,12 +248,12 @@ Grocy.Components.UserfieldsForm.Load = function() var formGroup = input.parent().parent().parent(); formGroup.find("label.custom-file-label").text(fileName); - formGroup.find(".userfield-file-show").attr('href', U('/files/userfiles/' + value)); + formGroup.find(".userfield-file-show").attr('href', U('/api/files/userfiles/' + value)); formGroup.find('.userfield-file-show').removeClass('d-none'); - formGroup.find('img.userfield-current-file').attr('src', U('/files/userfiles/' + value + '?force_serve_as=picture&best_fit_width=250&best_fit_height=250')); + formGroup.find('img.userfield-current-file').attr('src', U('/api/files/userfiles/' + value + '?force_serve_as=picture&best_fit_width=250&best_fit_height=250')); formGroup.find('.userfield-file-delete').click( - function() + function () { formGroup.find("label.custom-file-label").text(__t("No file selected")); formGroup.find(".userfield-file-show").addClass('d-none'); @@ -262,7 +262,7 @@ Grocy.Components.UserfieldsForm.Load = function() } ); - input.on("change", function(e) + input.on("change", function (e) { formGroup.find(".userfield-file-show").addClass('d-none'); }); @@ -287,12 +287,12 @@ Grocy.Components.UserfieldsForm.Load = function() } }); - $("form").each(function() + $("form").each(function () { Grocy.FrontendHelpers.ValidateForm(this.id); }); }, - function(xhr) + function (xhr) { console.error(xhr); } @@ -300,7 +300,7 @@ Grocy.Components.UserfieldsForm.Load = function() } } -Grocy.Components.UserfieldsForm.Clear = function() +Grocy.Components.UserfieldsForm.Clear = function () { if (!$("#userfields-form").length) { @@ -308,9 +308,9 @@ Grocy.Components.UserfieldsForm.Clear = function() } Grocy.Api.Get('objects/userfields?query[]=entity=' + $("#userfields-form").data("entity"), - function(result) + function (result) { - $.each(result, function(key, userfield) + $.each(result, function (key, userfield) { var input = $(".userfield-input[data-userfield-name='" + userfield.name + "']"); @@ -328,13 +328,13 @@ Grocy.Components.UserfieldsForm.Clear = function() var formGroup = input.parent().parent().parent(); formGroup.find("label.custom-file-label").text(""); - formGroup.find(".userfield-file-show").attr('href', U('/files/userfiles/' + value)); + formGroup.find(".userfield-file-show").attr('href', U('/api/files/userfiles/' + value)); formGroup.find('.userfield-file-show').removeClass('d-none'); formGroup.find('img.userfield-current-file') - .attr('src', U('/files/userfiles/' + value + '?force_serve_as=picture&best_fit_width=250&best_fit_height=250')); + .attr('src', U('/api/files/userfiles/' + value + '?force_serve_as=picture&best_fit_width=250&best_fit_height=250')); formGroup.find('.userfield-file-delete').click( - function() + function () { formGroup.find("label.custom-file-label").text(__t("No file selected")); formGroup.find(".userfield-file-show").addClass('d-none'); @@ -342,7 +342,7 @@ Grocy.Components.UserfieldsForm.Clear = function() } ); - input.on("change", function(e) + input.on("change", function (e) { formGroup.find(".userfield-file-show").addClass('d-none'); }); @@ -361,19 +361,19 @@ Grocy.Components.UserfieldsForm.Clear = function() } }); - $("form").each(function() + $("form").each(function () { Grocy.FrontendHelpers.ValidateForm(this.id); }); }, - function(xhr) + function (xhr) { console.error(xhr); } ); } -$(".userfield-link").keyup(function(e) +$(".userfield-link").keyup(function (e) { var formRow = $(this).parent().parent(); var title = formRow.find(".userfield-link-title").val(); @@ -387,15 +387,15 @@ $(".userfield-link").keyup(function(e) formRow.find(".userfield-input").val(JSON.stringify(value)).addClass("is-dirty"); }); -$(".userfield-input").change(function(e) +$(".userfield-input").change(function (e) { - $("form").each(function() + $("form").each(function () { Grocy.FrontendHelpers.ValidateForm(this.id); }); }); -$(".userfield-input.selectpicker").on("changed.bs.select", function() +$(".userfield-input.selectpicker").on("changed.bs.select", function () { $(this).addClass("is-dirty"); }); diff --git a/public/viewjs/equipment.js b/public/viewjs/equipment.js index 9fe3e66b..52e8e4cb 100644 --- a/public/viewjs/equipment.js +++ b/public/viewjs/equipment.js @@ -8,7 +8,7 @@ style: 'single', selector: 'tr td:not(:first-child)' }, - 'initComplete': function() + 'initComplete': function () { this.api().row({ order: 'current' }, 0).select(); DisplayEquipment($('#equipment-table tbody tr:eq(0)').data("equipment-id")); @@ -17,7 +17,7 @@ $('#equipment-table tbody').removeClass("d-none"); equipmentTable.columns.adjust().draw(); -equipmentTable.on('select', function(e, dt, type, indexes) +equipmentTable.on('select', function (e, dt, type, indexes) { if (type === 'row') { @@ -29,7 +29,7 @@ equipmentTable.on('select', function(e, dt, type, indexes) function DisplayEquipment(id) { Grocy.Api.Get('objects/equipment/' + id, - function(equipmentItem) + function (equipmentItem) { $(".selected-equipment-name").text(equipmentItem.name); $("#description-tab-content").html(equipmentItem.description); @@ -59,14 +59,14 @@ function DisplayEquipment(id) if (equipmentItem.userfields != null) { Grocy.Api.Get('objects/userfields?query[]=entity=equipment&query[]=type=file', - function(result) + function (result) { - $.each(result, function(key, userfield) + $.each(result, function (key, userfield) { var userfieldFile = equipmentItem.userfields[userfield.name]; if (userfieldFile) { - var pdfUrl = U('/files/userfiles/' + userfieldFile); + var pdfUrl = U('/api/files/userfiles/' + userfieldFile); $("#file-userfield-" + userfield.name + "-embed").attr("src", pdfUrl); $("#file-userfield-" + userfield.name + "-download-button").attr("href", pdfUrl); $("#file-userfield-" + userfield.name + "-embed").removeClass("d-none"); @@ -82,21 +82,21 @@ function DisplayEquipment(id) } }); }, - function(xhr) + function (xhr) { console.error(xhr); } ); } }, - function(xhr) + function (xhr) { console.error(xhr); } ); } -$("#search").on("keyup", Delay(function() +$("#search").on("keyup", Delay(function () { var value = $(this).val(); if (value === "all") @@ -107,13 +107,13 @@ $("#search").on("keyup", Delay(function() equipmentTable.search(value).draw(); }, Grocy.FormFocusDelay)); -$("#clear-filter-button").on("click", function() +$("#clear-filter-button").on("click", function () { $("#search").val(""); equipmentTable.search("").draw(); }); -$(document).on('click', '.equipment-delete-button', function(e) +$(document).on('click', '.equipment-delete-button', function (e) { var objectName = $(e.currentTarget).attr('data-equipment-name'); var objectId = $(e.currentTarget).attr('data-equipment-id'); @@ -131,16 +131,16 @@ $(document).on('click', '.equipment-delete-button', function(e) className: 'btn-danger' } }, - callback: function(result) + callback: function (result) { if (result === true) { Grocy.Api.Delete('objects/equipment/' + objectId, {}, - function(result) + function (result) { window.location.href = U('/equipment'); }, - function(xhr) + function (xhr) { console.error(xhr); } @@ -150,7 +150,7 @@ $(document).on('click', '.equipment-delete-button', function(e) }); }); -$(".selectedEquipmentInstructionManualToggleFullscreenButton").on('click', function(e) +$(".selectedEquipmentInstructionManualToggleFullscreenButton").on('click', function (e) { var button = $(e.currentTarget); var card = button.closest(".selectedEquipmentInstructionManualCard"); @@ -163,7 +163,7 @@ $(".selectedEquipmentInstructionManualToggleFullscreenButton").on('click', funct ResizeResponsiveEmbeds(); }); -$("#selectedEquipmentDescriptionToggleFullscreenButton").on('click', function(e) +$("#selectedEquipmentDescriptionToggleFullscreenButton").on('click', function (e) { $("#selectedEquipmentDescriptionCard").toggleClass("fullscreen"); $("#selectedEquipmentDescriptionCard .card-header").toggleClass("fixed-top"); diff --git a/routes.php b/routes.php index 56700737..51dd5a03 100644 --- a/routes.php +++ b/routes.php @@ -57,8 +57,6 @@ $app->group('', function (RouteCollectorProxy $group) $group->get('/user/{userId}/permissions', [UsersController::class, 'PermissionList']); $group->get('/usersettings', [UsersController::class, 'UserSettings']); - $group->get('/files/{group}/{fileName}', [FilesApiController::class, 'ShowFile']); - // Stock master data routes $group->get('/products', [StockController::class, 'ProductsList']); $group->get('/product/{productId}', [StockController::class, 'ProductEditForm']); diff --git a/views/components/userfields_tbody.blade.php b/views/components/userfields_tbody.blade.php index d3ed819c..87b83844 100644 --- a/views/components/userfields_tbody.blade.php +++ b/views/components/userfields_tbody.blade.php @@ -38,12 +38,12 @@ $excludeFieldTypes = []; {{ $title }} @elseif($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_FILE && !empty($userfieldObject->value)) - {{ base64_decode(explode('_', $userfieldObject->value)[1]) }} @elseif($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_IMAGE && !empty($userfieldObject->value)) - + {{ base64_decode(explode('_', $userfieldObject->value)[1]) }} diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index 5556f56d..81c45b6c 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -476,7 +476,7 @@ @else @endif {{ GROCY_USER_USERNAME }}