validate([ 'company_id' => ['nullable', 'integer'], 'subject' => ['required', 'string', 'max:200'], 'body' => ['required', 'string', 'min:10'], 'priority_id' => ['required', 'integer', Rule::exists('helpdesk_priorities', 'id')], 'category_id' => ['nullable', 'integer', Rule::exists('helpdesk_categories', 'id')], 'project_id' => ['nullable', 'integer', Rule::exists('helpdesk_projects', 'id')], 'product_id' => ['nullable', 'integer', Rule::exists('helpdesk_products', 'id')], 'team_id' => ['nullable', 'integer', Rule::exists('helpdesk_teams', 'id')], 'due_at' => ['nullable', 'date'], 'attachments' => ['nullable', 'array'], 'attachments.*' => $this->attachmentFileRules(), ]); $user = Auth::user(); abort_if($user === null, 403); $uploadedFiles = $request->file('attachments', []); $uploadedFiles = is_array($uploadedFiles) ? $uploadedFiles : [$uploadedFiles]; $ticket = $tickets->create($user, [ 'company_id' => $validated['company_id'] ?? null, 'subject' => $validated['subject'], 'body' => $validated['body'], 'priority_id' => $validated['priority_id'], 'category_id' => $validated['category_id'] ?? null, 'project_id' => $validated['project_id'] ?? null, 'product_id' => $validated['product_id'] ?? null, 'team_id' => $validated['team_id'] ?? null, 'due_at' => $validated['due_at'] ?? null, ], $uploadedFiles); return redirect() ->route('helpdesk.tickets.index') ->with('success', 'Ticket ' . $ticket->reference . ' has been created.'); } /** * Return Helpdesk attachment validation rules without relying on a newly autoloaded support class. * * @param bool $required Whether at least one uploaded file is required. * @return array */ private function attachmentFileRules(bool $required = false): array { return array_values(array_filter([ $required ? 'required' : null, 'file', 'max:' . (int) config('helpdesk.max_upload_kb', 10240), 'extensions:' . implode(',', $this->allowedAttachmentExtensions()), ])); } /** * Return lower-case Helpdesk attachment extensions. * * @return array */ private function allowedAttachmentExtensions(): array { return collect(config('helpdesk.allowed_extensions', config('helpdesk.allowed_mimes', []))) ->filter(static fn (mixed $extension): bool => is_string($extension) && trim($extension) !== '') ->map(static fn (string $extension): string => strtolower(ltrim(trim($extension), '.'))) ->unique() ->values() ->all(); } }