clusev/app/Livewire/Audit/Index.php

101 lines
3.0 KiB
PHP

<?php
namespace App\Livewire\Audit;
use App\Models\AuditEvent;
use App\Models\Setting;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Component;
#[Layout('layouts.app')]
class Index extends Component
{
/** Freitext-Filter über Akteur / Aktion / Ziel / Server. */
public string $q = '';
/**
* Aufbewahrungsdauer in Tagen (Formularfeld). Leer/0 = unbegrenzt; ein
* positiver Wert N löscht beim täglichen Prune Einträge älter als N Tage.
*/
public ?string $retentionDays = null;
public function mount(): void
{
// Empty/0 means "keep forever" — surface that as a blank field, not "0".
$stored = (int) Setting::get('audit_retention_days', '0');
$this->retentionDays = $stored > 0 ? (string) $stored : null;
}
/** Persist the retention policy, audit the change and notify the operator. */
public function saveRetention(): void
{
$validated = $this->validate([
'retentionDays' => ['nullable', 'integer', 'min:1', 'max:3650'],
]);
$days = $validated['retentionDays'] !== null && $validated['retentionDays'] !== ''
? (int) $validated['retentionDays']
: 0;
Setting::put('audit_retention_days', $days > 0 ? (string) $days : null);
$this->retentionDays = $days > 0 ? (string) $days : null;
AuditEvent::create([
'user_id' => Auth::id(),
'actor' => Auth::user()?->name ?? 'system',
'action' => 'audit.retention_set',
'target' => 'audit_retention_days='.$days,
'ip' => request()->ip(),
]);
$this->dispatch('notify', message: __('audit.retention_saved_notify'));
}
/** Effective retention in days (0 = unlimited) for the policy summary. */
protected function retentionPolicy(): int
{
return $this->retentionDays !== null && $this->retentionDays !== ''
? (int) $this->retentionDays
: 0;
}
/**
* Letzte Audit-Ereignisse, optional gefiltert. Echte Daten aus der DB;
* die Filterung läuft im Speicher über die geladenen 50 Einträge.
*/
protected function events(): Collection
{
$events = AuditEvent::with('server')->latest()->limit(50)->get();
$needle = trim($this->q);
if ($needle === '') {
return $events;
}
$needle = mb_strtolower($needle);
return $events->filter(function (AuditEvent $e) use ($needle): bool {
$haystack = mb_strtolower(implode(' ', array_filter([
$e->actor,
$e->action,
$e->action_label,
$e->target,
$e->server?->name,
])));
return str_contains($haystack, $needle);
})->values();
}
public function render()
{
return view('livewire.audit.index', [
'events' => $this->events(),
'retentionPolicy' => $this->retentionPolicy(),
])->title(__('audit.title'));
}
}