Files
2026-10-19 14:11:28 +01:00

93 lines
3.4 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Support;
use App\Http\Controllers\Controller;
use App\Models\SupportTicket;
use App\Models\User;
use App\Notifications\NewSupportTicket;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Str;
final class SupportController extends Controller
{
public function create(Request $request)
{
return view('support', [
'categories' => [
'technical' => 'Technical support',
'licensing' => 'Licence & activation',
'billing' => 'Billing & subscription',
'feature' => 'Feature request',
'privacy' => 'Privacy / data request',
'general' => 'General enquiry',
],
]);
}
public function store(Request $request): RedirectResponse
{
// Honeypot: bots tend to fill hidden fields. Return success without retaining spam.
if (filled($request->input('company_website'))) {
return back()->with('status', 'Your support request has been received.');
}
$data = $request->validate([
'name' => ['required', 'string', 'max:120'],
'email' => ['required', 'email:rfc', 'max:254'],
'category' => ['required', 'in:technical,licensing,billing,feature,privacy,general'],
'subject' => ['required', 'string', 'max:180'],
'message' => ['required', 'string', 'min:10', 'max:10000'],
'privacy_notice' => ['accepted'],
]);
$ticket = SupportTicket::create([
'user_id' => $request->user()?->id,
'reference' => $this->reference(),
'name' => $data['name'],
'email' => strtolower($data['email']),
'category' => $data['category'],
'subject' => $data['subject'],
'message' => $data['message'],
'privacy_notice_accepted_at' => now(),
]);
$this->notifyTeam($ticket);
Mail::raw(
"We received your Rsync Studio support request.\n\nReference: {$ticket->reference}\nSubject: {$ticket->subject}\n\nWe will reply to this email address. Please keep the reference in any follow-up.",
fn ($mail) => $mail->to($ticket->email)->subject("Rsync Studio support request {$ticket->reference}")
);
return redirect()->route('support')->with('status', "Support request {$ticket->reference} received. A confirmation has been emailed to you.");
}
private function notifyTeam(SupportTicket $ticket): void
{
if (config('rsync-studio.support.notify_admin_users', true)) {
User::query()->where('is_admin', true)->get()->each->notify(new NewSupportTicket($ticket));
}
$emails = collect(config('rsync-studio.support.alert_emails', []))
->filter(fn ($email) => filter_var($email, FILTER_VALIDATE_EMAIL))
->unique()
->values();
if ($emails->isNotEmpty()) {
Notification::route('mail', $emails->all())->notify(new NewSupportTicket($ticket));
}
}
private function reference(): string
{
do {
$reference = 'RS-'.now()->format('ymd').'-'.Str::upper(Str::random(6));
} while (SupportTicket::where('reference', $reference)->exists());
return $reference;
}
}