From e00d92a75b29de349784096ed45cc3600a451b03 Mon Sep 17 00:00:00 2001 From: TheOnlyMace <0815cracky@gmail.com> Date: Sun, 17 May 2026 14:32:08 +0200 Subject: [PATCH] Enhance VM creation request validation and UI. - Introduced `prepareForValidation` method to handle input merging for `behind_traefik` and `devices`. - Updated validation rules to conditionally require `subdomain` based on `behind_traefik`. - Added custom attribute names and error messages for better user feedback. - Improved the create VM form to dynamically show/hide subdomain fields based on the `behind_traefik` checkbox state. - Adjusted the user selection logic to display a message when no customers are available. --- app/Http/Requests/StoreVmRequest.php | 79 ++++++++++++++++++++++++++-- lang/de/validation.php | 28 ++++++++++ resources/views/vms/create.blade.php | 32 +++++++---- 3 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 lang/de/validation.php diff --git a/app/Http/Requests/StoreVmRequest.php b/app/Http/Requests/StoreVmRequest.php index bee0b15..2107aca 100644 --- a/app/Http/Requests/StoreVmRequest.php +++ b/app/Http/Requests/StoreVmRequest.php @@ -13,14 +13,55 @@ class StoreVmRequest extends FormRequest return $this->user()->can('create', Customer::class); } + protected function prepareForValidation(): void + { + $behindTraefik = $this->resolveBehindTraefik(); + + $merge = ['behind_traefik' => $behindTraefik]; + + if (! $behindTraefik) { + $merge['subdomain'] = null; + } + + if ($this->has('devices') && is_array($this->input('devices'))) { + $devices = collect($this->input('devices')) + ->filter(fn ($device) => is_array($device) && ! empty($device['type'])) + ->values() + ->all(); + + $merge['devices'] = $devices === [] ? null : $devices; + } + + $this->merge($merge); + } + + public function wantsTraefik(): bool + { + return $this->boolean('behind_traefik'); + } + + private function resolveBehindTraefik(): bool + { + if (! $this->has('behind_traefik')) { + return false; + } + + $value = $this->input('behind_traefik'); + + if (is_array($value)) { + return in_array('1', $value, true) || in_array(1, $value, true) || in_array(true, $value, true); + } + + return filter_var($value, FILTER_VALIDATE_BOOLEAN); + } + public function rules(): array { - $baseDomain = config('hosting.plesk.base_domain'); - return [ 'name' => ['required', 'string', 'max:100', 'regex:/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/'], 'subdomain' => [ - Rule::requiredIf(fn () => $this->boolean('behind_traefik')), + Rule::excludeIf(fn () => ! $this->wantsTraefik()), + Rule::requiredIf(fn () => $this->wantsTraefik()), 'nullable', 'string', 'max:63', @@ -28,7 +69,6 @@ class StoreVmRequest extends FormRequest ], 'behind_traefik' => ['boolean'], 'user_id' => [ - Rule::requiredIf(fn () => $this->user()->isAdmin()), 'nullable', 'exists:users,id', ], @@ -46,7 +86,7 @@ class StoreVmRequest extends FormRequest public function domain(): ?string { - if (! $this->boolean('behind_traefik') || ! $this->filled('subdomain')) { + if (! $this->wantsTraefik() || ! $this->filled('subdomain')) { return null; } @@ -61,4 +101,33 @@ class StoreVmRequest extends FormRequest return $this->user()->id; } + + /** + * @return array + */ + public function attributes(): array + { + return [ + 'name' => 'VM-Name', + 'subdomain' => 'Subdomain', + 'user_id' => 'Kunde', + 'cpu' => 'vCPUs', + 'ram' => 'RAM', + 'disk' => 'Festplatte', + 'install_iso' => 'Installations-ISO', + 'devices.*.type' => 'Gerätetyp', + ]; + } + + /** + * @return array + */ + public function messages(): array + { + return [ + 'required' => ':attribute ist erforderlich.', + 'regex' => ':attribute hat ein ungültiges Format.', + 'exists' => 'Der gewählte :attribute ist ungültig.', + ]; + } } diff --git a/lang/de/validation.php b/lang/de/validation.php new file mode 100644 index 0000000..ac94512 --- /dev/null +++ b/lang/de/validation.php @@ -0,0 +1,28 @@ + ':attribute muss akzeptiert werden.', + 'required' => ':attribute muss ausgefüllt werden.', + 'string' => ':attribute muss eine Zeichenkette sein.', + 'integer' => ':attribute muss eine ganze Zahl sein.', + 'boolean' => ':attribute muss wahr oder falsch sein.', + 'email' => ':attribute muss eine gültige E-Mail-Adresse sein.', + 'max' => [ + 'string' => ':attribute darf maximal :max Zeichen haben.', + 'integer' => ':attribute darf maximal :max sein.', + ], + 'min' => [ + 'string' => ':attribute muss mindestens :min Zeichen haben.', + 'integer' => ':attribute muss mindestens :min sein.', + ], + 'regex' => 'Das Format von :attribute ist ungültig.', + 'unique' => ':attribute ist bereits vergeben.', + 'confirmed' => ':attribute stimmt nicht mit der Bestätigung überein.', + 'exists' => 'Der gewählte :attribute ist ungültig.', + 'in' => 'Der gewählte :attribute ist ungültig.', + 'required_if' => ':attribute ist erforderlich, wenn :other :value ist.', + + 'attributes' => [], + +]; diff --git a/resources/views/vms/create.blade.php b/resources/views/vms/create.blade.php index e0c3c21..cb72eb6 100644 --- a/resources/views/vms/create.blade.php +++ b/resources/views/vms/create.blade.php @@ -13,30 +13,39 @@ - @if($customers->isNotEmpty()) + @if(auth()->user()->isAdmin()) @endif + @php + $behindTraefik = filter_var(old('behind_traefik', '1'), FILTER_VALIDATE_BOOLEAN); + @endphp -
+ @@ -90,7 +99,12 @@