getId(); } private function getHidden(): array { return \Cache::get($this->hiddenKey(), []); } private function saveHidden(array $ids): void { \Cache::put($this->hiddenKey(), array_values(array_unique($ids)), now()->addDays(7)); } public function deleteEntry(string $id): void { $hidden = $this->getHidden(); $hidden[] = $id; $this->saveHidden($hidden); } public function deleteCurrentTab(): void { $all = $this->fetchHistory(); $hidden = $this->getHidden(); $toHide = match($this->filter) { 'suspicious' => array_filter($all, fn($m) => $m['action'] !== 'no action'), 'all' => $all, default => array_filter($all, fn($m) => $m['action'] === $this->filter), }; foreach ($toHide as $m) { $hidden[] = $m['id']; } $this->saveHidden($hidden); $this->resetPage(); } public function updatedFilter(): void { $this->resetPage(); } public function updatedSearch(): void { $this->resetPage(); } public function updatedPerPage(): void { $this->resetPage(); } public function openMessage(string $msgId): void { $this->dispatch('openModal', component: 'ui.nx.mail.modal.quarantine-message-modal', arguments: ['msgId' => $msgId] ); } public function render() { $hidden = $this->getHidden(); $all = array_values(array_filter( $this->fetchHistory(), fn($m) => !in_array($m['id'], $hidden, true) )); $suspicious = array_values(array_filter($all, fn($m) => $m['action'] !== 'no action')); $counts = [ 'all' => count($all), 'suspicious' => count($suspicious), 'reject' => count(array_filter($all, fn($m) => $m['action'] === 'reject')), 'add header' => count(array_filter($all, fn($m) => $m['action'] === 'add header')), 'greylist' => count(array_filter($all, fn($m) => $m['action'] === 'greylist')), ]; $messages = match($this->filter) { 'suspicious' => $suspicious, 'all' => $all, default => array_values(array_filter($all, fn($m) => $m['action'] === $this->filter)), }; if ($this->search !== '') { $s = strtolower($this->search); $messages = array_values(array_filter($messages, fn($m) => str_contains(strtolower($m['from'] ?? ''), $s) || str_contains(strtolower($m['rcpt'] ?? ''), $s) || str_contains(strtolower($m['subject'] ?? ''), $s) )); } $total = count($messages); $currentPage = LengthAwarePaginator::resolveCurrentPage(); $paged = new LengthAwarePaginator( array_slice($messages, ($currentPage - 1) * $this->perPage, $this->perPage), $total, $this->perPage, $currentPage, ['path' => request()->url()] ); return view('livewire.ui.nx.mail.quarantine-list', [ 'messages' => $paged, 'counts' => $counts, ]); } // ── helpers ────────────────────────────────────────────────────────────── public function fetchHistory(): array { $password = env('RSPAMD_PASSWORD', ''); $opts = [ 'http' => [ 'timeout' => 3, 'ignore_errors' => true, 'header' => $password !== '' ? "Password: {$password}\r\n" : '', ], ]; $ctx = stream_context_create($opts); $raw = @file_get_contents("http://127.0.0.1:11334/history?rows={$this->rows}", false, $ctx); if (!$raw) return []; $data = json_decode($raw, true); if (!is_array($data)) return []; $items = $data['rows'] ?? (isset($data[0]) ? $data : []); return array_map(function ($r) { $rcpt = $r['rcpt'] ?? []; if (is_array($rcpt)) $rcpt = implode(', ', $rcpt); return [ 'id' => $r['scan_id'] ?? ($r['id'] ?? uniqid('q_')), 'msg_id' => $r['message-id'] ?? '—', 'from' => $r['from'] ?? $r['sender'] ?? '—', 'rcpt' => $rcpt ?: '—', 'subject' => $r['subject'] ?? '(kein Betreff)', 'score' => round((float)($r['score'] ?? 0), 2), 'required' => round((float)($r['required_score'] ?? 15), 2), 'action' => $r['action'] ?? 'unknown', 'time' => (int)($r['unix_time'] ?? $r['time'] ?? 0), 'size' => (int)($r['size'] ?? 0), 'symbols' => array_keys($r['symbols'] ?? []), 'ip' => $r['ip'] ?? '—', ]; }, $items); } }