94 lines
3.6 KiB
PHP
Executable File
94 lines
3.6 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Http\Controllers;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Validation\Rule;
|
|
use Modules\Helpdesk\Services\TicketService;
|
|
|
|
final class TicketStoreController extends Controller
|
|
{
|
|
/**
|
|
* Store a new helpdesk ticket using a normal HTTP form post.
|
|
*
|
|
* This avoids the Livewire update endpoint for ticket creation, which prevents
|
|
* proxy/hash update-route 404s from blocking ticket creation.
|
|
*/
|
|
public function __invoke(Request $request, TicketService $tickets): RedirectResponse
|
|
{
|
|
$validated = $request->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<int, string>
|
|
*/
|
|
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<int, string>
|
|
*/
|
|
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();
|
|
}
|
|
}
|