redirect(route('ui.webmail.login')); return; } // Restore staged attachments from session, drop any whose files were cleaned up $staged = session('compose_attachments', []); $this->stagedAttachments = array_values( array_filter($staged, fn($a) => Storage::exists($a['path'])) ); $user = MailUser::where('email', session('webmail_email'))->first(); $prefs = $user?->webmail_prefs ?? []; $sig = (string) ($user?->signature ?? ''); if ($this->draftUid > 0) { $this->loadDraft(); return; } // Signatur laden — wird NICHT in den Body injiziert, sondern separat angezeigt if ($sig) { $this->signatureIsHtml = (bool) preg_match('/<[a-zA-Z][^>]*>/', $sig); $applyNew = ($prefs['signature_new'] ?? true); $applyReply = ($prefs['signature_reply'] ?? false); if ($this->replyUid > 0 && $applyReply) { $this->signatureRaw = $sig; } elseif ($this->replyUid === 0 && $applyNew) { $this->signatureRaw = $sig; } } if ($this->replyUid > 0) { $this->loadReply(); return; } } // Called by Livewire when $attachments changes (after upload completes) public function updatedAttachments(): void { $dir = 'webmail-tmp/' . session()->getId(); foreach ($this->attachments as $file) { $filename = uniqid('att_') . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '_', $file->getClientOriginalName()); $path = $file->storeAs($dir, $filename, 'local'); $this->stagedAttachments[] = [ 'name' => $file->getClientOriginalName(), 'size' => $file->getSize(), 'mime' => $file->getMimeType() ?: 'application/octet-stream', 'path' => $path, ]; } $this->attachments = []; session(['compose_attachments' => $this->stagedAttachments]); } private function loadDraft(): void { $this->isDraft = true; try { $imap = app(ImapService::class); $client = $imap->client(session('webmail_email'), session('webmail_password')); $orig = $imap->getMessage($client, $this->draftFolder, $this->draftUid); $client->disconnect(); $this->to = $orig['to'] ?? ''; $this->subject = $orig['subject'] ?? ''; $this->body = $orig['text'] ?? strip_tags($orig['html'] ?? ''); } catch (\Throwable) {} } private function loadReply(): void { $this->isReply = true; try { $imap = app(ImapService::class); $client = $imap->client(session('webmail_email'), session('webmail_password')); $orig = $imap->getMessage($client, $this->replyFolder, $this->replyUid); $client->disconnect(); $this->to = $orig['from'] ?? ''; $sub = $orig['subject'] ?? ''; $this->subject = str_starts_with(strtolower($sub), 're:') ? $sub : 'Re: ' . $sub; $date = $orig['date'] ? \Carbon\Carbon::parse($orig['date'])->format('d.m.Y \u\m H:i \U\h\r') : ''; $fromName = $orig['from_name'] ?: ($orig['from'] ?? ''); $fromAddr = $orig['from'] ?? ''; $this->replyMeta = "Am {$date} schrieb {$fromName} <{$fromAddr}>:"; $quoteText = $orig['text'] ?: strip_tags($orig['html'] ?? ''); $quoted = implode("\n", array_map( fn($l) => '> ' . $l, explode("\n", rtrim($quoteText)) )); $this->body = "\n\n\n" . $this->replyMeta . "\n" . $quoted; } catch (\Throwable) {} } public function back(): void { $hasContent = trim($this->to) || trim($this->subject) || trim(preg_replace('/^[\s>]+$/m', '', $this->body)); if ($hasContent) { $this->saveCurrentDraft(true); } $this->clearStagedAttachments(); $this->redirect(route('ui.webmail.inbox')); } public function send(): void { $this->validate([ 'to' => 'required|email', 'subject' => 'required|string|max:255', 'body' => 'required|string', ]); try { $imap = app(ImapService::class); if ($this->signatureIsHtml && $this->signatureRaw) { $htmlBody = '