mailwolt/app/Livewire/Ui/Mail/Modal/AliasFormModal.php

2200 lines
83 KiB
PHP

<?php
namespace App\Livewire\Ui\Mail\Modal;
use App\Models\Domain;
use App\Models\MailAlias;
use App\Models\MailUser;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use LivewireUI\Modal\ModalComponent;
class AliasFormModal extends ModalComponent
{
// Eingabe / State
public ?int $aliasId = null;
public ?int $domainId = null;
public string $local = '';
public string $type = 'single'; // single|group
public ?string $group_name = null;
public bool $is_active = true;
public ?string $notes = null;
public array $recipients = [];
// UI
public int $maxGroupRecipients = 20;
public bool $canAddRecipient = false;
public array $rowState = [];
public array $disabledMailboxIdsByRow = [];
public array $rowDuplicateError = [];
// Lookup
public ?Domain $domain = null;
/** @var \Illuminate\Support\Collection<int,\App\Models\MailUser> */
public $domainMailUsers;
// -------------------- Lifecycle --------------------
public function mount(?int $aliasId = null, ?int $domainId = null): void
{
$this->aliasId = $aliasId;
$this->domainId = $domainId;
if ($this->aliasId) {
$alias = MailAlias::with(['domain', 'recipients.mailUser'])->findOrFail($this->aliasId);
if ($alias->domain->is_system) abort(403, 'System-Domains sind für Aliasse gesperrt.');
$this->domain = $alias->domain;
$this->domainId = $alias->domain_id;
$this->fill([
'local' => $alias->local,
'type' => $alias->type,
'group_name' => $alias->group_name,
'is_active' => $alias->is_active,
'notes' => $alias->notes,
]);
// vorhandene Empfänger -> mit stabiler id versehen
$this->recipients = $alias->recipients
->map(fn($r) => [
'id' => (string)Str::uuid(),
'mail_user_id' => $r->mail_user_id,
'email' => $r->email,
])
->all();
} else {
$this->domain = $this->domainId
? Domain::where('is_system', false)->findOrFail($this->domainId)
: Domain::where('is_system', false)->orderBy('domain')->first();
$this->domainId = $this->domain->id ?? null;
$this->recipients = [[
'id' => (string)Str::uuid(),
'mail_user_id' => null,
'email' => null,
]];
}
$this->domainMailUsers = $this->domain
? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
: collect();
$this->ensureAtLeastOneRow();
$this->recomputeUi();
$this->validateRecipientDuplicates();
}
// -------------------- UI-Reaktionen --------------------
public function updated($name, $value): void
{
// XOR je Zeile
if (preg_match('/^recipients\.(\d+)\.(mail_user_id|email)$/', $name, $m)) {
$i = (int)$m[1];
if ($m[2] === 'mail_user_id' && !empty($value)) {
$this->recipients[$i]['email'] = null;
} elseif ($m[2] === 'email') {
$this->recipients[$i]['mail_user_id'] = null;
$this->recipients[$i]['email'] = Str::lower(trim((string)$this->recipients[$i]['email']));
}
}
// Self-Loop Live-Feedback (extern == alias)
if (preg_match('/^recipients\.(\d+)\.email$/', $name, $m)) {
$i = (int)$m[1];
$self = $this->currentAliasAddress();
$this->resetErrorBag("recipients.$i.email");
if ($self && Str::lower(trim((string)$this->recipients[$i]['email'])) === $self) {
$this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
}
}
if ($name === 'type' && $this->type === 'single') {
$first = $this->recipients[0] ?? ['id' => (string)Str::uuid(), 'mail_user_id' => null, 'email' => null];
$first['id'] = $first['id'] ?? (string)Str::uuid();
$this->recipients = [$first];
}
$this->ensureAtLeastOneRow();
$this->recomputeUi();
$this->validateRecipientDuplicates();
}
public function updatedType(string $value): void
{
if ($value === 'single') {
$first = $this->recipients[0] ?? ['id' => (string)Str::uuid(), 'mail_user_id' => null, 'email' => null];
$first['id'] = $first['id'] ?? (string)Str::uuid();
$this->recipients = [$first];
$this->recomputeUi();
$this->validateRecipientDuplicates();
}
}
public function updatedDomainId(): void
{
$this->domain = $this->domainId
? Domain::where('is_system', false)->find($this->domainId)
: null;
$this->domainMailUsers = $this->domain
? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
: collect();
// Zeilen resetten (neue Domain)
$this->recipients = [[
'id' => (string)Str::uuid(),
'mail_user_id' => null,
'email' => null,
]];
$this->ensureAtLeastOneRow();
$this->recomputeUi();
$this->validateRecipientDuplicates();
}
public function addRecipientRow(): void
{
if ($this->type === 'single') return;
if (count($this->recipients) >= $this->maxGroupRecipients) return;
$this->recipients[] = ['id' => (string)Str::uuid(), 'mail_user_id' => null, 'email' => null];
$this->recomputeUi();
}
public function removeRecipientRow(int $index): void
{
unset($this->recipients[$index]);
$this->recipients = array_values($this->recipients);
$this->ensureAtLeastOneRow();
$this->recomputeUi();
$this->validateRecipientDuplicates();
}
// -------------------- Helpers --------------------
private function currentAliasAddress(): ?string
{
if (!$this->domainId || $this->local === '') return null;
$domainName = $this->domain?->domain ?? Domain::find($this->domainId)?->domain;
if (!$domainName) return null;
return Str::lower(trim($this->local)) . '@' . Str::lower($domainName);
}
private function ensureAtLeastOneRow(): void
{
if (empty($this->recipients)) {
$this->recipients = [[
'id' => (string)Str::uuid(),
'mail_user_id' => null,
'email' => null,
]];
}
}
private function recomputeUi(): void
{
$count = count($this->recipients);
$this->canAddRecipient = $this->type === 'group' && $count < $this->maxGroupRecipients;
$usedMailboxIds = [];
$usedExternal = [];
foreach ($this->recipients as $r) {
if (!empty($r['mail_user_id'])) $usedMailboxIds[] = (int)$r['mail_user_id'];
if (!empty($r['email'])) $usedExternal[] = Str::lower(trim((string)$r['email']));
}
$this->disabledMailboxIdsByRow = [];
$this->rowState = [];
$this->rowDuplicateError = [];
$aliasAddr = $this->currentAliasAddress();
for ($i = 0; $i < $count; $i++) {
$myId = (int)($this->recipients[$i]['mail_user_id'] ?? 0);
$hasInternal = $myId > 0;
$hasExternal = !empty($this->recipients[$i]['email']);
$myExternal = Str::lower(trim((string)($this->recipients[$i]['email'] ?? '')));
// andere interne IDs sperren
$disabled = array_values(array_unique(array_filter(
$usedMailboxIds, fn($id) => $id && $id !== $myId
)));
// interne IDs sperren, deren Adresse in externen Feldern vorkommt
if ($this->domain) {
foreach ($this->domainMailUsers as $mu) {
$addr = Str::lower($mu->localpart . '@' . $this->domain->domain);
if (in_array($addr, $usedExternal, true) && $mu->id !== $myId) {
$disabled[] = (int)$mu->id;
}
}
}
$this->disabledMailboxIdsByRow[$i] = array_values(array_unique($disabled));
$this->rowState[$i] = [
'disable_internal' => $hasExternal || ($aliasAddr && $aliasAddr === $myExternal),
'disable_external' => $hasInternal,
'can_remove' => !($this->type === 'single' && $count === 1),
];
}
}
private function validateRecipientDuplicates(): bool
{
$this->resetErrorBag();
$values = [];
$byAddr = [];
foreach ($this->recipients as $i => $r) {
$addr = null;
if (!empty($r['mail_user_id']) && $this->domain) {
$u = MailUser::find((int)$r['mail_user_id']);
if ($u) $addr = Str::lower($u->localpart . '@' . $this->domain->domain);
} elseif (!empty($r['email'])) {
$addr = Str::lower(trim((string)$r['email']));
}
if ($addr) {
$values[$i] = $addr;
$byAddr[$addr] = $byAddr[$addr] ?? [];
$byAddr[$addr][] = $i;
}
}
$hasDupes = false;
foreach ($byAddr as $addr => $idxs) {
if (count($idxs) <= 1) continue;
$hasDupes = true;
foreach ($idxs as $i) {
if (!empty($this->recipients[$i]['mail_user_id'])) {
$this->addError("recipients.$i.mail_user_id", 'Dieser Empfänger ist bereits hinzugefügt.');
} else {
$this->addError("recipients.$i.email", 'Dieser Empfänger ist bereits hinzugefügt.');
}
}
}
return $hasDupes;
}
private function aliasConflictsWithMailbox(): bool
{
if (!$this->domainId || $this->local === '') return false;
$local = Str::lower(trim($this->local));
return MailUser::query()
->where('domain_id', $this->domainId)
->whereRaw('LOWER(localpart) = ?', [$local])
->exists();
}
// -------------------- Save --------------------
public function save(): void
{
$this->validate($this->rules(), $this->messages());
foreach ($this->recipients as $i => $r) {
if (empty($r['mail_user_id']) && empty($r['email'])) {
$this->addError("recipients.$i.email", 'Wähle internes Postfach oder externe E-Mail.');
return;
}
}
if ($this->validateRecipientDuplicates()) return;
if ($aliasAddr = $this->currentAliasAddress()) {
foreach ($this->recipients as $i => $r) {
if (!empty($r['email']) && Str::lower(trim((string)$r['email'])) === $aliasAddr) {
$this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
return;
}
if (!empty($r['mail_user_id'])) {
$u = MailUser::find((int)$r['mail_user_id']);
if ($u && $this->domain && Str::lower($u->localpart . '@' . $this->domain->domain) === $aliasAddr) {
$this->addError("recipients.$i.mail_user_id", 'Alias darf nicht an sich selbst weiterleiten.');
return;
}
}
}
}
if ($this->aliasConflictsWithMailbox()) {
$this->addError('local', 'Diese Adresse ist bereits als Postfach vergeben.');
return;
}
$rows = collect($this->recipients)
->map(fn($r) => [
'mail_user_id' => $r['mail_user_id'] ?: null,
'email' => isset($r['email']) && $r['email'] !== '' ? Str::lower(trim($r['email'])) : null,
])
->filter(fn($r) => $r['mail_user_id'] || $r['email'])
->values();
$isUpdate = (bool) $this->aliasId;
DB::transaction(function () use ($rows) {
/** @var MailAlias $alias */
$alias = MailAlias::updateOrCreate(
['id' => $this->aliasId],
[
'domain_id' => $this->domainId,
'local' => $this->local,
'type' => $this->type,
'group_name' => $this->type === 'group' ? ($this->group_name ?: null) : null,
'is_active' => $this->is_active,
'notes' => $this->notes,
]
);
$alias->recipients()->delete();
foreach ($rows as $i => $r) {
$alias->recipients()->create([
'mail_user_id' => $r['mail_user_id'],
'email' => $r['email'],
'position' => $i,
]);
}
$this->aliasId = $alias->id;
});
$email = $this->currentAliasAddress();
if (!$email) {
$domainName = $this->domain?->domain ?? optional(\App\Models\Domain::find($this->domainId))->domain;
$email = trim(strtolower($this->local)) . '@' . trim(strtolower((string) $domainName));
}
$this->dispatch('alias:' . ($this->aliasId ? 'updated' : 'created'));
$this->dispatch('closeModal');
$typeLabel = $this->type === 'single' ? 'Single-Alias' : 'Gruppen-Alias';
$action = $this->aliasId ? 'aktualisiert' : 'erstellt';
$this->dispatch('toast',
type: 'done',
badge: 'Alias',
title: "$typeLabel $action",
text: "Der $typeLabel <b>" . e($email) . "</b> wurde erfolgreich $action.",
duration: 6000
);
}
// -------------------- Validation --------------------
protected function rules(): array
{
$occupied = $this->domainId
? MailUser::query()
->where('domain_id', $this->domainId)
->pluck('localpart')
->map(fn($l) => Str::lower($l))
->all()
: [];
return [
'domainId' => ['required', 'exists:domains,id'],
'local' => [
'required',
'regex:/^[A-Za-z0-9._%+-]+$/',
Rule::unique('mail_aliases', 'local')
->ignore($this->aliasId)
->where(fn($q) => $q->where('domain_id', $this->domainId)),
Rule::notIn($occupied),
],
'type' => ['required', 'in:single,group'],
'group_name' => ['nullable','string','max:80','required_if:type,group'],
'recipients' => ['array', 'min:1', 'max:' . ($this->type === 'single' ? 1 : $this->maxGroupRecipients)],
'recipients.*.mail_user_id' => ['nullable', 'exists:mail_users,id'],
'recipients.*.email' => ['nullable', 'email:rfc'],
];
}
protected function messages(): array
{
return [
'local.required' => 'Alias-Adresse ist erforderlich.',
'local.regex' => 'Erlaubt sind Buchstaben, Zahlen und ._%+-',
'local.unique' => 'Dieser Alias existiert in dieser Domain bereits.',
'local.not_in' => 'Diese Adresse ist bereits als Postfach vergeben.',
'recipients.min' => 'Mindestens ein Empfänger ist erforderlich.',
'recipients.max' => $this->type === 'single'
? 'Bei „Single“ ist nur ein Empfänger zulässig.'
: 'Maximal ' . $this->maxGroupRecipients . ' Empfänger erlaubt.',
];
}
public function render()
{
return view('livewire.ui.mail.modal.alias-form-modal', [
'domains' => Domain::where('is_system', false)->orderBy('domain')->get(['id', 'domain']),
]);
}
}
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\Domain;
//use App\Models\MailAlias;
//use App\Models\MailUser;
//use Illuminate\Support\Facades\DB;
//use Illuminate\Support\Str;
//use Illuminate\Validation\Rule;
//use LivewireUI\Modal\ModalComponent;
//
//class AliasFormModal extends ModalComponent
//{
// // Eingabe / State
// public ?int $aliasId = null;
// public ?int $domainId = null;
// public string $local = '';
// public string $type = 'single'; // single|group
// public bool $is_active = true;
// public ?string $notes = null;
//
// // Empfänger-Zeilen (each: ['mail_user_id'=>?int, 'email'=>?string])
// public array $recipients = [];
//
// // Stabile Keys je Zeile (für wire:key im Blade)
// public array $rowKeys = [];
//
// // UI-Steuerung (nur Ausgabe im Blade)
// public int $maxGroupRecipients = 20;
// public bool $canAddRecipient = false; // „+ Empfänger“ erlauben
// public array $rowState = []; // [i => ['disable_internal'=>bool,'disable_external'=>bool,'can_remove'=>bool]]
// public array $disabledMailboxIdsByRow = []; // [i => [ids...]]
//
// // Lookup
// public ?Domain $domain = null;
// /** @var \Illuminate\Support\Collection<int,\App\Models\MailUser> */
// public $domainMailUsers;
//
// // -------------------- Lifecycle --------------------
//
// public function mount(?int $aliasId = null, ?int $domainId = null): void
// {
// $this->aliasId = $aliasId;
// $this->domainId = $domainId;
//
// if ($this->aliasId) {
// $alias = MailAlias::with(['domain', 'recipients.mailUser'])->findOrFail($this->aliasId);
// if ($alias->domain->is_system) {
// abort(403, 'System-Domains sind für Aliasse gesperrt.');
// }
// $this->domain = $alias->domain;
// $this->domainId = $alias->domain_id;
//
// $this->fill([
// 'local' => $alias->local,
// 'type' => $alias->type,
// 'is_active' => $alias->is_active,
// 'notes' => $alias->notes,
// ]);
//
// $this->recipients = $alias->recipients
// ->map(fn($r) => ['mail_user_id' => $r->mail_user_id, 'email' => $r->email])
// ->all();
// } else {
// // erste Nicht-System-Domain
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->findOrFail($this->domainId)
// : Domain::where('is_system', false)->orderBy('domain')->first();
//
// $this->domainId = $this->domain->id ?? null;
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// $this->ensureAtLeastOneRow();
// $this->syncRowKeysToRecipients();
//
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // sofortige Feldfehler bei vorbefüllten Daten
// }
//
// // -------------------- UI-Reaktionen --------------------
//
// public function updated($name, $value): void
// {
// // XOR: wenn intern gesetzt -> extern leeren, und umgekehrt
// if (preg_match('/^recipients\.(\d+)\.(mail_user_id|email)$/', $name, $m)) {
// $i = (int)$m[1];
// if ($m[2] === 'mail_user_id' && !empty($value)) {
// $this->recipients[$i]['email'] = null;
// } elseif ($m[2] === 'email') {
// $this->recipients[$i]['mail_user_id'] = null;
// $this->recipients[$i]['email'] = Str::lower(trim((string)$this->recipients[$i]['email']));
// }
// }
//
// // Self-Loop Live-Feedback: extern == alias
// if (preg_match('/^recipients\.(\d+)\.email$/', $name, $m)) {
// $i = (int)$m[1];
// $self = $this->currentAliasAddress();
// $this->resetErrorBag("recipients.$i.email");
// if ($self && Str::lower(trim((string)$this->recipients[$i]['email'])) === $self) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// }
// }
//
// if ($name === 'type' && $this->type === 'single') {
// $this->recipients = [$this->recipients[0] ?? ['mail_user_id' => null, 'email' => null]];
// }
//
// $this->ensureAtLeastOneRow();
// $this->syncRowKeysToRecipients();
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // feldgenaues Feedback live
// }
//
// public function updatedType(string $value): void
// {
// if ($value === 'single') {
// $first = $this->recipients[0] ?? ['mail_user_id' => null, 'email' => null];
// $this->recipients = [$first];
// $this->syncRowKeysToRecipients();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
// }
//
// public function updatedDomainId(): void
// {
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->find($this->domainId)
// : null;
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// // Zeilen resetten, weil Empfänger domaingebunden sind
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
//
// $this->ensureAtLeastOneRow();
// $this->syncRowKeysToRecipients();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// public function addRecipientRow(): void
// {
// if ($this->type === 'single') return;
// if (count($this->recipients) >= $this->maxGroupRecipients) return;
//
// $this->recipients[] = ['mail_user_id' => null, 'email' => null];
// $this->rowKeys[] = (string)Str::uuid(); // stabiler Key für neue Zeile
//
// $this->recomputeUi();
// // kein Duplicate hier, weil leer
// }
//
// public function removeRecipientRow(int $index): void
// {
// unset($this->recipients[$index], $this->rowKeys[$index]);
// $this->recipients = array_values($this->recipients);
// $this->rowKeys = array_values($this->rowKeys);
//
// $this->ensureAtLeastOneRow();
// $this->syncRowKeysToRecipients();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// // -------------------- Helpers --------------------
//
// // vollständige Alias-Adresse (z.B. "info@pixio.at") oder null
// private function currentAliasAddress(): ?string
// {
// if (!$this->domainId || $this->local === '') return null;
//
// $domainName = $this->domain?->domain ?? Domain::find($this->domainId)?->domain;
// if (!$domainName) return null;
//
// return Str::lower(trim($this->local)) . '@' . Str::lower($domainName);
// }
//
// private function ensureAtLeastOneRow(): void
// {
// if (empty($this->recipients)) {
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
// }
//
// // rowKeys-Liste immer an recipients-Länge anpassen (stabile wire:key Werte)
// private function syncRowKeysToRecipients(): void
// {
// $need = count($this->recipients);
// $have = count($this->rowKeys);
//
// // auffüllen
// while ($have < $need) {
// $this->rowKeys[] = (string)Str::uuid();
// $have++;
// }
// // kürzen
// if ($have > $need) {
// $this->rowKeys = array_slice($this->rowKeys, 0, $need);
// }
// }
//
// // UI neu berechnen (inkl. Self-Loop-Schutz)
// private function recomputeUi(): void
// {
// $count = count($this->recipients);
// $this->canAddRecipient = $this->type === 'group' && $count < $this->maxGroupRecipients;
//
// // bereits gewählte interne IDs und externe Adressen einsammeln
// $usedMailboxIds = [];
// $usedExternalAddr = [];
//
// foreach ($this->recipients as $r) {
// if (!empty($r['mail_user_id'])) $usedMailboxIds[] = (int)$r['mail_user_id'];
// if (!empty($r['email'])) $usedExternalAddr[] = Str::lower(trim((string)$r['email']));
// }
//
// $this->disabledMailboxIdsByRow = [];
// $this->rowState = [];
//
// // Aktuelle Alias-Adresse für Self-Loop-Checks
// $aliasAddr = $this->currentAliasAddress();
//
// for ($i = 0; $i < $count; $i++) {
// $myId = (int)($this->recipients[$i]['mail_user_id'] ?? 0);
// $hasInternal = $myId > 0;
// $hasExternal = !empty($this->recipients[$i]['email']);
// $myExternal = Str::lower(trim((string)($this->recipients[$i]['email'] ?? '')));
//
// // andere bereits gewählte interne IDs sperren
// $disabled = array_values(array_unique(array_filter(
// $usedMailboxIds, fn($id) => $id && $id !== $myId
// )));
//
// // interne IDs zusätzlich sperren, deren Adresse in irgendeinem externen Feld steht
// if ($this->domain) {
// foreach ($this->domainMailUsers as $mu) {
// $addr = Str::lower($mu->localpart . '@' . $this->domain->domain);
// if (in_array($addr, $usedExternalAddr, true) && $mu->id !== $myId) {
// $disabled[] = (int)$mu->id;
// }
// }
// }
//
// $this->disabledMailboxIdsByRow[$i] = array_values(array_unique($disabled));
//
// // Self-Loop: wenn extern == alias, internen Picker sperren
// $disableInternal = $hasExternal || ($aliasAddr && $aliasAddr === $myExternal);
//
// $this->rowState[$i] = [
// 'disable_internal' => $disableInternal, // XOR + Self-Loop
// 'disable_external' => $hasInternal, // XOR
// 'can_remove' => !($this->type === 'single' && $count === 1),
// ];
// }
// }
//
// // Duplikate feldgenau markieren (keine Exceptions)
// private function validateRecipientDuplicates(): bool
// {
// // komplette Empfänger-Fehler zurücksetzen
// $this->resetErrorBag();
//
// // Map Zeile -> normalisierte Zieladresse (intern => local@domain, extern => email)
// $values = []; // [i => 'addr']
// $byAddrIndices = []; // 'addr' => [i1,i2,...]
//
// foreach ($this->recipients as $i => $r) {
// $addr = null;
//
// if (!empty($r['mail_user_id'])) {
// if ($this->domain) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u) $addr = Str::lower($u->localpart . '@' . $this->domain->domain);
// }
// } elseif (!empty($r['email'])) {
// $addr = Str::lower(trim((string)$r['email']));
// }
//
// if ($addr) {
// $values[$i] = $addr;
// $byAddrIndices[$addr] = $byAddrIndices[$addr] ?? [];
// $byAddrIndices[$addr][] = $i;
// }
// }
//
// $hasDupes = false;
//
// foreach ($byAddrIndices as $addr => $indices) {
// if (count($indices) <= 1) continue;
// $hasDupes = true;
// // alle betroffenen Felder markieren (feldgenau)
// foreach ($indices as $i) {
// if (!empty($this->recipients[$i]['mail_user_id'])) {
// $this->addError("recipients.$i.mail_user_id", 'Dieser Empfänger ist bereits hinzugefügt.');
// } else {
// $this->addError("recipients.$i.email", 'Dieser Empfänger ist bereits hinzugefügt.');
// }
// }
// }
//
// return $hasDupes;
// }
//
// private function aliasConflictsWithMailbox(): bool
// {
// if (!$this->domainId || $this->local === '') return false;
//
// $local = Str::lower(trim($this->local));
// return MailUser::query()
// ->where('domain_id', $this->domainId)
// ->whereRaw('LOWER(localpart) = ?', [$local])
// ->exists();
// }
//
// // -------------------- Save --------------------
//
// public function save(): void
// {
// // 1) Basisregeln
// $this->validate($this->rules(), $this->messages());
//
// // 2) Zeilen dürfen nicht leer sein (weder intern noch extern)
// foreach ($this->recipients as $i => $r) {
// if (empty($r['mail_user_id']) && empty($r['email'])) {
// $this->addError("recipients.$i.email", 'Wähle internes Postfach oder externe E-Mail.');
// return;
// }
// }
//
// // 3) Duplikate feldgenau prüfen
// if ($this->validateRecipientDuplicates()) {
// return;
// }
//
// // 3b) Self-Loop final abfangen
// if ($aliasAddr = $this->currentAliasAddress()) {
// foreach ($this->recipients as $i => $r) {
// // extern
// if (!empty($r['email']) && Str::lower(trim((string)$r['email'])) === $aliasAddr) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// // intern (falls je relevant)
// if (!empty($r['mail_user_id'])) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u && $this->domain && Str::lower($u->localpart . '@' . $this->domain->domain) === $aliasAddr) {
// $this->addError("recipients.$i.mail_user_id", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// }
// }
// }
//
// // 4) Alias-Adresse darf kein bestehendes Postfach sein
// if ($this->aliasConflictsWithMailbox()) {
// $this->addError('local', 'Diese Adresse ist bereits als Postfach vergeben.');
// return;
// }
//
// // 5) Persistieren
// $rows = collect($this->recipients)
// ->map(fn($r) => [
// 'mail_user_id' => $r['mail_user_id'] ?: null,
// 'email' => isset($r['email']) && $r['email'] !== '' ? Str::lower(trim($r['email'])) : null,
// ])
// ->filter(fn($r) => $r['mail_user_id'] || $r['email'])
// ->values();
//
// DB::transaction(function () use ($rows) {
// /** @var MailAlias $alias */
// $alias = MailAlias::updateOrCreate(
// ['id' => $this->aliasId],
// [
// 'domain_id' => $this->domainId,
// 'local' => $this->local,
// 'type' => $this->type,
// 'is_active' => $this->is_active,
// 'notes' => $this->notes,
// ]
// );
//
// $alias->recipients()->delete();
// foreach ($rows as $i => $r) {
// $alias->recipients()->create([
// 'mail_user_id' => $r['mail_user_id'],
// 'email' => $r['email'],
// 'position' => $i,
// ]);
// }
//
// $this->aliasId = $alias->id;
// });
//
// $this->dispatch('alias:' . ($this->aliasId ? 'updated' : 'created'));
// $this->dispatch('closeModal');
// }
//
// // -------------------- Validation --------------------
//
// protected function rules(): array
// {
// // blocke offensichtliche Kollisionen mit Mailboxen (gleiche Domain)
// $occupied = $this->domainId
// ? MailUser::query()
// ->where('domain_id', $this->domainId)
// ->pluck('localpart')
// ->map(fn($l) => Str::lower($l))
// ->all()
// : [];
//
// return [
// 'domainId' => ['required', 'exists:domains,id'],
// 'local' => [
// 'required',
// 'regex:/^[A-Za-z0-9._%+-]+$/',
// Rule::unique('mail_aliases', 'local')
// ->ignore($this->aliasId)
// ->where(fn($q) => $q->where('domain_id', $this->domainId)),
// Rule::notIn($occupied),
// ],
// 'type' => ['required', 'in:single,group'],
//
// 'recipients' => ['array', 'min:1', 'max:' . ($this->type === 'single' ? 1 : $this->maxGroupRecipients)],
// 'recipients.*.mail_user_id' => ['nullable', 'exists:mail_users,id'],
// 'recipients.*.email' => ['nullable', 'email:rfc'],
// ];
// }
//
// protected function messages(): array
// {
// return [
// 'local.required' => 'Alias-Adresse ist erforderlich.',
// 'local.regex' => 'Erlaubt sind Buchstaben, Zahlen und ._%+-',
// 'local.unique' => 'Dieser Alias existiert in dieser Domain bereits.',
// 'local.not_in' => 'Diese Adresse ist bereits als Postfach vergeben.',
// 'recipients.min' => 'Mindestens ein Empfänger ist erforderlich.',
// 'recipients.max' => $this->type === 'single'
// ? 'Bei „Single“ ist nur ein Empfänger zulässig.'
// : 'Maximal ' . $this->maxGroupRecipients . ' Empfänger erlaubt.',
// ];
// }
//
// public function render()
// {
// return view('livewire.ui.mail.modal.alias-form-modal', [
// 'domains' => Domain::where('is_system', false)
// ->orderBy('domain')
// ->get(['id', 'domain']),
// ]);
// }
//}
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\Domain;
//use App\Models\MailAlias;
//use App\Models\MailUser;
//use Illuminate\Support\Facades\DB;
//use Illuminate\Support\Str;
//use Illuminate\Validation\Rule;
//use LivewireUI\Modal\ModalComponent;
//
//class AliasFormModal extends ModalComponent
//{
// // Eingabe / State
// public ?int $aliasId = null;
// public ?int $domainId = null;
// public string $local = '';
// public string $type = 'single'; // single|group
// public bool $is_active = true;
// public ?string $notes = null;
//
// // Empfänger-Zeilen (each: ['mail_user_id'=>?int, 'email'=>?string])
// public array $recipients = [];
//
// // UI-Steuerung (nur Ausgabe im Blade)
// public int $maxGroupRecipients = 20;
// public bool $canAddRecipient = false; // „+ Empfänger“ erlauben
// public array $rowState = []; // [i => ['disable_internal'=>bool,'disable_external'=>bool,'can_remove'=>bool]]
// public array $disabledMailboxIdsByRow = []; // [i => [ids...]]
//
// // Lookup
// public ?Domain $domain = null;
// /** @var \Illuminate\Support\Collection<int,\App\Models\MailUser> */
// public $domainMailUsers;
//
// // -------------------- Lifecycle --------------------
//
// public function mount(?int $aliasId = null, ?int $domainId = null): void
// {
// $this->aliasId = $aliasId;
// $this->domainId = $domainId;
//
// if ($this->aliasId) {
// $alias = MailAlias::with(['domain', 'recipients.mailUser'])->findOrFail($this->aliasId);
// if ($alias->domain->is_system) {
// abort(403, 'System-Domains sind für Aliasse gesperrt.');
// }
// $this->domain = $alias->domain;
// $this->domainId = $alias->domain_id;
//
// $this->fill([
// 'local' => $alias->local,
// 'type' => $alias->type,
// 'is_active' => $alias->is_active,
// 'notes' => $alias->notes,
// ]);
//
// $this->recipients = $alias->recipients
// ->map(fn($r) => ['mail_user_id' => $r->mail_user_id, 'email' => $r->email])
// ->all();
// } else {
// // erste Nicht-System-Domain
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->findOrFail($this->domainId)
// : Domain::where('is_system', false)->orderBy('domain')->first();
//
// $this->domainId = $this->domain->id ?? null;
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // sofortige Feldfehler bei vorbefüllten Daten
// }
//
// // -------------------- UI-Reaktionen --------------------
//
// public function updated($name, $value): void
// {
// // XOR: wenn intern gesetzt -> extern leeren, und umgekehrt
// if (preg_match('/^recipients\.(\d+)\.(mail_user_id|email)$/', $name, $m)) {
// $i = (int)$m[1];
// if ($m[2] === 'mail_user_id' && !empty($value)) {
// $this->recipients[$i]['email'] = null;
// } elseif ($m[2] === 'email') {
// $this->recipients[$i]['mail_user_id'] = null;
// $this->recipients[$i]['email'] = Str::lower(trim((string)$this->recipients[$i]['email']));
// }
// }
//
// // Self-Loop Live-Feedback: extern == alias
// if (preg_match('/^recipients\.(\d+)\.email$/', $name, $m)) {
// $i = (int)$m[1];
// $self = $this->currentAliasAddress();
// $this->resetErrorBag("recipients.$i.email");
// if ($self && Str::lower(trim((string)$this->recipients[$i]['email'])) === $self) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// }
// }
//
// if ($name === 'type' && $this->type === 'single') {
// $this->recipients = [$this->recipients[0] ?? ['mail_user_id' => null, 'email' => null]];
// }
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // feldgenaues Feedback live
// }
//
// public function updatedType(string $value): void
// {
// if ($value === 'single') {
// $first = $this->recipients[0] ?? ['mail_user_id' => null, 'email' => null];
// $this->recipients = [$first];
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
// }
//
// public function updatedDomainId(): void
// {
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->find($this->domainId)
// : null;
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// // Zeilen resetten, weil Empfänger domaingebunden sind
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// public function addRecipientRow(): void
// {
// if ($this->type === 'single') return;
// if (count($this->recipients) >= $this->maxGroupRecipients) return;
//
// $this->recipients[] = ['mail_user_id' => null, 'email' => null];
// $this->recomputeUi();
// }
//
// public function removeRecipientRow(int $index): void
// {
// unset($this->recipients[$index]);
// $this->recipients = array_values($this->recipients);
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// // -------------------- Helpers --------------------
//
// // vollständige Alias-Adresse (z.B. "info@pixio.at") oder null
// private function currentAliasAddress(): ?string
// {
// if (!$this->domainId || $this->local === '') return null;
//
// $domainName = $this->domain?->domain ?? Domain::find($this->domainId)?->domain;
// if (!$domainName) return null;
//
// return Str::lower(trim($this->local)) . '@' . Str::lower($domainName);
// }
//
// private function ensureAtLeastOneRow(): void
// {
// if (empty($this->recipients)) {
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
// }
//
// // UI neu berechnen (inkl. Self-Loop-Schutz)
// private function recomputeUi(): void
// {
// $count = count($this->recipients);
// $this->canAddRecipient = $this->type === 'group' && $count < $this->maxGroupRecipients;
//
// // bereits gewählte interne IDs und externe Adressen einsammeln
// $usedMailboxIds = [];
// $usedExternalAddr = [];
//
// foreach ($this->recipients as $r) {
// if (!empty($r['mail_user_id'])) $usedMailboxIds[] = (int)$r['mail_user_id'];
// if (!empty($r['email'])) $usedExternalAddr[] = Str::lower(trim((string)$r['email']));
// }
//
// $this->disabledMailboxIdsByRow = [];
// $this->rowState = [];
//
// // Aktuelle Alias-Adresse für Self-Loop-Checks
// $aliasAddr = $this->currentAliasAddress();
//
// for ($i = 0; $i < $count; $i++) {
// $myId = (int)($this->recipients[$i]['mail_user_id'] ?? 0);
// $hasInternal = $myId > 0;
// $hasExternal = !empty($this->recipients[$i]['email']);
// $myExternal = Str::lower(trim((string)($this->recipients[$i]['email'] ?? '')));
//
// // andere bereits gewählte internen IDs sperren
// $disabled = array_values(array_unique(array_filter(
// $usedMailboxIds, fn($id) => $id && $id !== $myId
// )));
//
// // interne IDs zusätzlich sperren, deren Adresse in irgendeinem externen Feld steht
// if ($this->domain) {
// foreach ($this->domainMailUsers as $mu) {
// $addr = Str::lower($mu->localpart . '@' . $this->domain->domain);
// if (in_array($addr, $usedExternalAddr, true) && $mu->id !== $myId) {
// $disabled[] = (int)$mu->id;
// }
// }
// }
//
// $this->disabledMailboxIdsByRow[$i] = array_values(array_unique($disabled));
//
// // Self-Loop verhindern: wenn extern == alias, internen Picker sperren
// $disableInternal = $hasExternal || ($aliasAddr && $aliasAddr === $myExternal);
//
// $this->rowState[$i] = [
// 'disable_internal' => $disableInternal, // XOR + Self-Loop
// 'disable_external' => $hasInternal, // XOR
// 'can_remove' => !($this->type === 'single' && $count === 1),
// ];
// }
// }
//
// // Duplikate feldgenau markieren (keine Exceptions)
// private function validateRecipientDuplicates(): bool
// {
// // komplette Empfänger-Fehler zurücksetzen
// $this->resetErrorBag();
//
// // Map Zeile -> normalisierte Zieladresse (intern => local@domain, extern => email)
// $values = []; // [i => 'addr']
// $byAddrIndices = []; // 'addr' => [i1,i2,...]
//
// foreach ($this->recipients as $i => $r) {
// $addr = null;
//
// if (!empty($r['mail_user_id'])) {
// if ($this->domain) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u) $addr = Str::lower($u->localpart . '@' . $this->domain->domain);
// }
// } elseif (!empty($r['email'])) {
// $addr = Str::lower(trim((string)$r['email']));
// }
//
// if ($addr) {
// $values[$i] = $addr;
// $byAddrIndices[$addr] = $byAddrIndices[$addr] ?? [];
// $byAddrIndices[$addr][] = $i;
// }
// }
//
// $hasDupes = false;
//
// foreach ($byAddrIndices as $addr => $indices) {
// if (count($indices) <= 1) continue;
// $hasDupes = true;
// // alle betroffenen Felder markieren (feldgenau)
// foreach ($indices as $i) {
// if (!empty($this->recipients[$i]['mail_user_id'])) {
// $this->addError("recipients.$i.mail_user_id", 'Dieser Empfänger ist bereits hinzugefügt.');
// } else {
// $this->addError("recipients.$i.email", 'Dieser Empfänger ist bereits hinzugefügt.');
// }
// }
// }
//
// return $hasDupes;
// }
//
// private function aliasConflictsWithMailbox(): bool
// {
// if (!$this->domainId || $this->local === '') return false;
//
// $local = Str::lower(trim($this->local));
// return MailUser::query()
// ->where('domain_id', $this->domainId)
// ->whereRaw('LOWER(localpart) = ?', [$local])
// ->exists();
// }
//
// // -------------------- Save --------------------
//
// public function save(): void
// {
// // 1) Basisregeln
// $this->validate($this->rules(), $this->messages());
//
// // 2) Zeilen dürfen nicht leer sein (weder intern noch extern)
// foreach ($this->recipients as $i => $r) {
// if (empty($r['mail_user_id']) && empty($r['email'])) {
// $this->addError("recipients.$i.email", 'Wähle internes Postfach oder externe E-Mail.');
// return;
// }
// }
//
// // 3) Duplikate feldgenau prüfen
// if ($this->validateRecipientDuplicates()) {
// return;
// }
//
// // 3b) Self-Loop final abfangen
// if ($aliasAddr = $this->currentAliasAddress()) {
// foreach ($this->recipients as $i => $r) {
// // extern
// if (!empty($r['email']) && Str::lower(trim((string)$r['email'])) === $aliasAddr) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// // intern (falls je relevant)
// if (!empty($r['mail_user_id'])) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u && $this->domain && Str::lower($u->localpart . '@' . $this->domain->domain) === $aliasAddr) {
// $this->addError("recipients.$i.mail_user_id", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// }
// }
// }
//
// // 4) Alias-Adresse darf kein bestehendes Postfach sein
// if ($this->aliasConflictsWithMailbox()) {
// $this->addError('local', 'Diese Adresse ist bereits als Postfach vergeben.');
// return;
// }
//
// // 5) Persistieren
// $rows = collect($this->recipients)
// ->map(fn($r) => [
// 'mail_user_id' => $r['mail_user_id'] ?: null,
// 'email' => isset($r['email']) && $r['email'] !== '' ? Str::lower(trim($r['email'])) : null,
// ])
// ->filter(fn($r) => $r['mail_user_id'] || $r['email'])
// ->values();
//
// DB::transaction(function () use ($rows) {
// /** @var MailAlias $alias */
// $alias = MailAlias::updateOrCreate(
// ['id' => $this->aliasId],
// [
// 'domain_id' => $this->domainId,
// 'local' => $this->local,
// 'type' => $this->type,
// 'is_active' => $this->is_active,
// 'notes' => $this->notes,
// ]
// );
//
// $alias->recipients()->delete();
// foreach ($rows as $i => $r) {
// $alias->recipients()->create([
// 'mail_user_id' => $r['mail_user_id'],
// 'email' => $r['email'],
// 'position' => $i,
// ]);
// }
//
// $this->aliasId = $alias->id;
// });
//
// $this->dispatch('alias:' . ($this->aliasId ? 'updated' : 'created'));
// $this->dispatch('closeModal');
// }
//
// // -------------------- Validation --------------------
//
// protected function rules(): array
// {
// // blocke offensichtliche Kollisionen mit Mailboxen (gleiche Domain)
// $occupied = $this->domainId
// ? MailUser::query()
// ->where('domain_id', $this->domainId)
// ->pluck('localpart')
// ->map(fn($l) => Str::lower($l))
// ->all()
// : [];
//
// return [
// 'domainId' => ['required', 'exists:domains,id'],
// 'local' => [
// 'required',
// 'regex:/^[A-Za-z0-9._%+-]+$/',
// Rule::unique('mail_aliases', 'local')
// ->ignore($this->aliasId)
// ->where(fn($q) => $q->where('domain_id', $this->domainId)),
// Rule::notIn($occupied),
// ],
// 'type' => ['required', 'in:single,group'],
//
// 'recipients' => ['array', 'min:1', 'max:' . ($this->type === 'single' ? 1 : $this->maxGroupRecipients)],
// 'recipients.*.mail_user_id' => ['nullable', 'exists:mail_users,id'],
// 'recipients.*.email' => ['nullable', 'email:rfc'],
// ];
// }
//
// protected function messages(): array
// {
// return [
// 'local.required' => 'Alias-Adresse ist erforderlich.',
// 'local.regex' => 'Erlaubt sind Buchstaben, Zahlen und ._%+-',
// 'local.unique' => 'Dieser Alias existiert in dieser Domain bereits.',
// 'local.not_in' => 'Diese Adresse ist bereits als Postfach vergeben.',
// 'recipients.min' => 'Mindestens ein Empfänger ist erforderlich.',
// 'recipients.max' => $this->type === 'single'
// ? 'Bei „Single“ ist nur ein Empfänger zulässig.'
// : 'Maximal ' . $this->maxGroupRecipients . ' Empfänger erlaubt.',
// ];
// }
//
// public function render()
// {
// return view('livewire.ui.mail.modal.alias-form-modal', [
// 'domains' => Domain::where('is_system', false)
// ->orderBy('domain')
// ->get(['id', 'domain']),
// ]);
// }
//}
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\Domain;
//use App\Models\MailAlias;
//use App\Models\MailUser;
//use Illuminate\Support\Facades\DB;
//use Illuminate\Support\Str;
//use Illuminate\Validation\Rule;
//use LivewireUI\Modal\ModalComponent;
//
//class AliasFormModal extends ModalComponent
//{
// // Eingabe / State
// public ?int $aliasId = null;
// public ?int $domainId = null;
// public string $local = '';
// public string $type = 'single'; // single|group
// public bool $is_active = true;
// public ?string $notes = null;
//
// // Empfänger-Zeilen (each: ['mail_user_id'=>?int, 'email'=>?string])
// public array $recipients = [];
//
// // UI-Steuerung (nur Ausgabe im Blade)
// public int $maxGroupRecipients = 20;
// public bool $canAddRecipient = false; // „+ Empfänger“ erlauben
// public array $rowState = []; // [i => ['disable_internal'=>bool,'disable_external'=>bool,'can_remove'=>bool]]
// public array $disabledMailboxIdsByRow = []; // [i => [ids...]]
//
// // Lookup
// public ?Domain $domain = null;
// /** @var \Illuminate\Support\Collection<int,\App\Models\MailUser> */
// public $domainMailUsers;
//
// // -------------------- Lifecycle --------------------
//
// public function mount(?int $aliasId = null, ?int $domainId = null): void
// {
// $this->aliasId = $aliasId;
// $this->domainId = $domainId;
//
// if ($this->aliasId) {
// $alias = MailAlias::with(['domain','recipients.mailUser'])->findOrFail($this->aliasId);
// if ($alias->domain->is_system) {
// abort(403, 'System-Domains sind für Aliasse gesperrt.');
// }
// $this->domain = $alias->domain;
// $this->domainId = $alias->domain_id;
//
// $this->fill([
// 'local' => $alias->local,
// 'type' => $alias->type,
// 'is_active' => $alias->is_active,
// 'notes' => $alias->notes,
// ]);
//
// $this->recipients = $alias->recipients
// ->map(fn($r) => ['mail_user_id' => $r->mail_user_id, 'email' => $r->email])
// ->all();
// } else {
// // erste Nicht-System-Domain
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->findOrFail($this->domainId)
// : Domain::where('is_system', false)->orderBy('domain')->first();
//
// $this->domainId = $this->domain->id ?? null;
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // sofortige Feldfehler bei vorbefüllten Daten
// }
//
// // -------------------- UI-Reaktionen --------------------
//
// public function updated($name, $value): void
// {
// // XOR: wenn intern gesetzt -> extern leeren, und umgekehrt
// if (preg_match('/^recipients\.(\d+)\.(mail_user_id|email)$/', $name, $m)) {
// $i = (int)$m[1];
// if ($m[2] === 'mail_user_id' && !empty($value)) {
// $this->recipients[$i]['email'] = null;
// } elseif ($m[2] === 'email') {
// $this->recipients[$i]['mail_user_id'] = null;
// $this->recipients[$i]['email'] = Str::lower(trim((string)$this->recipients[$i]['email']));
// }
// }
//
// if (preg_match('/^recipients\.(\d+)\.email$/', $name, $m)) {
// $i = (int)$m[1];
// $self = $this->currentAliasAddress();
// $this->resetErrorBag("recipients.$i.email");
// if ($self && \Illuminate\Support\Str::lower(trim((string)$this->recipients[$i]['email'])) === $self) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// }
// }
//
// if ($name === 'type' && $this->type === 'single') {
// $this->recipients = [ $this->recipients[0] ?? ['mail_user_id'=>null,'email'=>null] ];
// }
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates(); // feldgenaues Feedback live
// }
//
// public function updatedType(string $value): void
// {
// if ($value === 'single') {
// $first = $this->recipients[0] ?? ['mail_user_id'=>null,'email'=>null];
// $this->recipients = [ $first ];
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
// }
//
// public function updatedDomainId(): void
// {
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->find($this->domainId)
// : null;
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// // Zeilen resetten, weil Empfänger domaingebunden sind
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// public function addRecipientRow(): void
// {
// if ($this->type === 'single') return;
// if (count($this->recipients) >= $this->maxGroupRecipients) return;
//
// $this->recipients[] = ['mail_user_id'=>null,'email'=>null];
// $this->recomputeUi();
// // kein Duplicate hier, weil leer
// }
//
// public function removeRecipientRow(int $index): void
// {
// unset($this->recipients[$index]);
// $this->recipients = array_values($this->recipients);
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// $this->validateRecipientDuplicates();
// }
//
// // -------------------- Helpers --------------------
//
// private function currentAliasAddress(): ?string
// {
// if (!$this->domainId || $this->local === '' || !$this->domain) return null;
// return \Illuminate\Support\Str::lower(trim($this->local).'@'.$this->domain->domain);
// }
//
// private function ensureAtLeastOneRow(): void
// {
// if (empty($this->recipients)) {
// $this->recipients = [['mail_user_id'=>null,'email'=>null]];
// }
// }
//
// private function recomputeUi(): void
// {
// $count = count($this->recipients);
// $this->canAddRecipient = $this->type === 'group' && $count < $this->maxGroupRecipients;
//
// // bereits gewählte interne IDs und externe Adressen einsammeln
// $usedMailboxIds = [];
// $usedExternalAddrs = []; // ['a@b.tld', ...] normalisiert
//
// foreach ($this->recipients as $r) {
// if (!empty($r['mail_user_id'])) $usedMailboxIds[] = (int)$r['mail_user_id'];
// if (!empty($r['email'])) $usedExternalAddrs[] = Str::lower(trim((string)$r['email']));
// }
//
// $this->disabledMailboxIdsByRow = [];
// $this->rowState = [];
//
// // Helper: internes Postfach -> vollständige Adresse
// $mailboxEmail = function (?int $id): ?string {
// if (!$id || !$this->domain) return null;
// $u = MailUser::find($id);
// return $u ? Str::lower($u->localpart.'@'.$this->domain->domain) : null;
// };
//
// for ($i = 0; $i < $count; $i++) {
// $myId = (int)($this->recipients[$i]['mail_user_id'] ?? 0);
// $hasInternal = $myId > 0;
// $hasExternal = !empty($this->recipients[$i]['email']);
//
// // Basis: andere bereits gewählte interne IDs sperren
// $disabled = array_values(array_unique(array_filter(
// $usedMailboxIds, fn($id) => $id && $id !== $myId
// )));
//
// // Zusätzlich: interne IDs sperren, deren Adresse in irgendeinem externen Feld steht
// if ($this->domain) {
// foreach ($this->domainMailUsers as $mu) {
// $addr = Str::lower($mu->localpart.'@'.$this->domain->domain);
// if (in_array($addr, $usedExternalAddrs, true) && $mu->id !== $myId) {
// $disabled[] = (int)$mu->id;
// }
// }
// }
//
// $this->disabledMailboxIdsByRow[$i] = array_values(array_unique($disabled));
//
// $this->rowState[$i] = [
// 'disable_internal' => $hasExternal, // XOR
// 'disable_external' => $hasInternal, // XOR
// 'can_remove' => !($this->type === 'single' && $count === 1),
// ];
// }
// }
//
//
// // Duplikate feldgenau markieren (keine Exceptions)
// private function validateRecipientDuplicates(): bool
// {
// // komplette Empfänger-Fehler zurücksetzen
// $this->resetErrorBag();
//
// // Map Zeile -> normalisierte Zieladresse (intern => local@domain, extern => email)
// $values = []; // [i => 'addr']
// $byAddrIndices = []; // 'addr' => [i1,i2,...]
//
// foreach ($this->recipients as $i => $r) {
// $addr = null;
//
// if (!empty($r['mail_user_id'])) {
// if ($this->domain) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u) $addr = Str::lower($u->localpart.'@'.$this->domain->domain);
// }
// } elseif (!empty($r['email'])) {
// $addr = Str::lower(trim((string)$r['email']));
// }
//
// if ($addr) {
// $values[$i] = $addr;
// $byAddrIndices[$addr] = $byAddrIndices[$addr] ?? [];
// $byAddrIndices[$addr][] = $i;
// }
// }
//
// $hasDupes = false;
//
// foreach ($byAddrIndices as $addr => $indices) {
// if (count($indices) <= 1) continue;
// $hasDupes = true;
// // alle betroffenen Felder markieren (feldgenau)
// foreach ($indices as $i) {
// if (!empty($this->recipients[$i]['mail_user_id'])) {
// $this->addError("recipients.$i.mail_user_id", 'Dieser Empfänger ist bereits hinzugefügt.');
// } else {
// $this->addError("recipients.$i.email", 'Dieser Empfänger ist bereits hinzugefügt.');
// }
// }
// }
//
// return $hasDupes;
// }
//
// private function aliasConflictsWithMailbox(): bool
// {
// if (!$this->domainId || $this->local === '') return false;
//
// $local = Str::lower(trim($this->local));
// return MailUser::query()
// ->where('domain_id', $this->domainId)
// ->whereRaw('LOWER(localpart) = ?', [$local])
// ->exists();
// }
//
// // -------------------- Save --------------------
//
// public function save(): void
// {
// // 1) Basisregeln
// $this->validate($this->rules(), $this->messages());
//
// // 2) Zeilen dürfen nicht leer sein (weder intern noch extern)
// foreach ($this->recipients as $i => $r) {
// if (empty($r['mail_user_id']) && empty($r['email'])) {
// $this->addError("recipients.$i.email", 'Wähle internes Postfach oder externe E-Mail.');
// return;
// }
// }
//
// // 3) Duplikate feldgenau prüfen
// if ($this->validateRecipientDuplicates()) {
// return;
// }
//
// if ($aliasAddr = $this->currentAliasAddress()) {
// foreach ($this->recipients as $i => $r) {
// // extern
// if (!empty($r['email']) && \Illuminate\Support\Str::lower(trim((string)$r['email'])) === $aliasAddr) {
// $this->addError("recipients.$i.email", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// // intern (falls es später mal interne Empfänger ohne existierendes Postfach geben sollte)
// if (!empty($r['mail_user_id'])) {
// $u = \App\Models\MailUser::find((int)$r['mail_user_id']);
// if ($u && $this->domain && \Illuminate\Support\Str::lower($u->localpart.'@'.$this->domain->domain) === $aliasAddr) {
// $this->addError("recipients.$i.mail_user_id", 'Alias darf nicht an sich selbst weiterleiten.');
// return;
// }
// }
// }
// }
//
// // 4) Alias-Adresse darf kein bestehendes Postfach sein
// if ($this->aliasConflictsWithMailbox()) {
// $this->addError('local', 'Diese Adresse ist bereits als Postfach vergeben.');
// return;
// }
//
// // 5) Persistieren
// $rows = collect($this->recipients)
// ->map(fn($r) => [
// 'mail_user_id' => $r['mail_user_id'] ?: null,
// 'email' => isset($r['email']) && $r['email'] !== '' ? Str::lower(trim($r['email'])) : null,
// ])
// ->filter(fn($r) => $r['mail_user_id'] || $r['email'])
// ->values();
//
// DB::transaction(function () use ($rows) {
// /** @var MailAlias $alias */
// $alias = MailAlias::updateOrCreate(
// ['id' => $this->aliasId],
// [
// 'domain_id' => $this->domainId,
// 'local' => $this->local,
// 'type' => $this->type,
// 'is_active' => $this->is_active,
// 'notes' => $this->notes,
// ]
// );
//
// $alias->recipients()->delete();
// foreach ($rows as $i => $r) {
// $alias->recipients()->create([
// 'mail_user_id' => $r['mail_user_id'],
// 'email' => $r['email'],
// 'position' => $i,
// ]);
// }
//
// $this->aliasId = $alias->id;
// });
//
// $this->dispatch('alias:' . ($this->aliasId ? 'updated' : 'created'));
// $this->dispatch('closeModal');
// }
//
// // -------------------- Validation --------------------
//
// protected function rules(): array
// {
// // blocke offensichtliche Kollisionen mit Mailboxen (gleiche Domain)
// $occupied = $this->domainId
// ? MailUser::query()
// ->where('domain_id', $this->domainId)
// ->pluck('localpart')
// ->map(fn($l) => Str::lower($l))
// ->all()
// : [];
//
// return [
// 'domainId' => ['required','exists:domains,id'],
// 'local' => [
// 'required',
// 'regex:/^[A-Za-z0-9._%+-]+$/',
// Rule::unique('mail_aliases','local')
// ->ignore($this->aliasId)
// ->where(fn($q) => $q->where('domain_id', $this->domainId)),
// Rule::notIn($occupied),
// ],
// 'type' => ['required','in:single,group'],
//
// 'recipients' => ['array','min:1','max:'.($this->type==='single' ? 1 : $this->maxGroupRecipients)],
// 'recipients.*.mail_user_id' => ['nullable','exists:mail_users,id'],
// 'recipients.*.email' => ['nullable','email:rfc'],
// ];
// }
//
// protected function messages(): array
// {
// return [
// 'local.required' => 'Alias-Adresse ist erforderlich.',
// 'local.regex' => 'Erlaubt sind Buchstaben, Zahlen und ._%+-',
// 'local.unique' => 'Dieser Alias existiert in dieser Domain bereits.',
// 'local.not_in' => 'Diese Adresse ist bereits als Postfach vergeben.',
// 'recipients.min' => 'Mindestens ein Empfänger ist erforderlich.',
// 'recipients.max' => $this->type === 'single'
// ? 'Bei „Single“ ist nur ein Empfänger zulässig.'
// : 'Maximal '.$this->maxGroupRecipients.' Empfänger erlaubt.',
// ];
// }
//
// public function render()
// {
// return view('livewire.ui.mail.modal.alias-form-modal', [
// 'domains' => Domain::where('is_system', false)
// ->orderBy('domain')
// ->get(['id','domain']),
// ]);
// }
//}
//
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\Domain;
//use App\Models\MailAlias;
//use App\Models\MailAliasRecipient;
//use App\Models\MailUser;
//use Illuminate\Support\Facades\DB;
//use Illuminate\Support\Str;
//use Illuminate\Validation\Rule;
//use Livewire\Attributes\On;
//use LivewireUI\Modal\ModalComponent;
//
//class AliasFormModal extends ModalComponent
//{
// // Eingabe-Props
// public ?int $aliasId = null; // wenn gesetzt -> Edit
// public ?int $domainId = null; // Create: vorbelegen (oder Auswahl)
// public string $local = '';
// public string $type = 'single'; // 'single' | 'group'
// public bool $is_active = true;
// public ?string $notes = null;
// public int $maxGroupRecipients = 20;
// public bool $canAddRecipient = false;
// public array $rowState = [];
// public array $disabledMailboxIdsByRow = [];
//
// // optionale UI-Fehler pro Zeile (Anzeige)
// public array $rowDuplicateError = [];
//
// public array $recipients = [];
//
// // UI-Daten
// public ?Domain $domain = null;
// /** @var \Illuminate\Support\Collection<int,MailUser> */
// public $domainMailUsers;
//
// public function mount(?int $aliasId = null, ?int $domainId = null): void
// {
// $this->aliasId = $aliasId;
// $this->domainId = $domainId;
//
// if ($this->aliasId) {
// $alias = MailAlias::with(['domain','recipients.mailUser'])->findOrFail($this->aliasId);
// if ($alias->domain->is_system) {
// abort(403, 'System-Domains sind für Aliasse gesperrt.');
// }
// $this->domain = $alias->domain;
// $this->domainId = $alias->domain_id;
//
// $this->fill([
// 'local' => $alias->local,
// 'type' => $alias->type,
// 'is_active' => $alias->is_active,
// 'notes' => $alias->notes,
// ]);
//
// $this->recipients = $alias->recipients->map(fn($r) => [
// 'mail_user_id' => $r->mail_user_id,
// 'email' => $r->email,
// ])->all();
// } else {
// // Erst NICHT-System-Domain
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->findOrFail($this->domainId)
// : Domain::where('is_system', false)->orderBy('domain')->first();
//
// $this->domainId = $this->domain->id ?? null;
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
// }
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// }
//
// public function updatedType(string $value): void
// {
// if ($value === 'single') {
// // exakt eine Zeile behalten
// $first = $this->recipients[0] ?? ['mail_user_id'=>null,'email'=>null];
// $this->recipients = [ $first ];
// }
// }
//
// private function validateRecipientDuplicates(): bool
// {
// // vorhandene Feldfehler für Empfänger leeren
// $this->resetErrorBag('recipients');
//
// // Map: Zielstring je Zeile -> Anzahl
// $values = []; // [i => 'office@pixio.at']
// $counts = []; // 'office@pixio.at' => n
//
// foreach ($this->recipients as $i => $r) {
// $val = null;
//
// if (!empty($r['mail_user_id'])) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u && $this->domain) {
// $val = Str::lower($u->localpart.'@'.$this->domain->domain);
// }
// } elseif (!empty($r['email'])) {
// $val = Str::lower(trim((string)$r['email']));
// }
//
// if ($val) {
// $values[$i] = $val;
// $counts[$val] = ($counts[$val] ?? 0) + 1;
// }
// }
//
// $hasDupes = false;
//
// foreach ($values as $i => $val) {
// if (($counts[$val] ?? 0) > 1) {
// // Feldgenau markieren
// if (!empty($this->recipients[$i]['mail_user_id'])) {
// $this->addError("recipients.$i.mail_user_id", 'Dieser Empfänger ist bereits hinzugefügt.');
// } else {
// $this->addError("recipients.$i.email", 'Dieser Empfänger ist bereits hinzugefügt.');
// }
// $hasDupes = true;
// }
// }
//
// return $hasDupes;
// }
//
//
// // Livewire v3: universeller Hook für verschachtelte Felder
// public function updated($name, $value): void
// {
// // XOR je Zeile
// if (preg_match('/^recipients\.(\d+)\.(mail_user_id|email)$/', $name, $m)) {
// $i = (int)$m[1];
// if ($m[2] === 'mail_user_id' && !empty($value)) {
// $this->recipients[$i]['email'] = null;
// } elseif ($m[2] === 'email' && !empty($value)) {
// $this->recipients[$i]['mail_user_id'] = null;
// $this->recipients[$i]['email'] = Str::lower(trim((string)$this->recipients[$i]['email']));
// }
// }
//
// if ($name === 'type' && $this->type === 'single') {
// $this->recipients = [ $this->recipients[0] ?? ['mail_user_id'=>null,'email'=>null] ];
// }
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
//
// // sofortiges, feldgenaues Duplikat-Feedback
// $this->validateRecipientDuplicates();
// }
//
// public function addRecipientRow(): void
// {
// if ($this->type === 'single') return;
// if (count($this->recipients) >= $this->maxGroupRecipients) return;
//
// $this->recipients[] = ['mail_user_id'=>null,'email'=>null];
// $this->recomputeUi();
// }
//
// public function updatedDomainId(): void
// {
// $this->domain = $this->domainId
// ? Domain::where('is_system', false)->find($this->domainId)
// : null;
//
// $this->domainMailUsers = $this->domain
// ? MailUser::where('domain_id', $this->domain->id)->orderBy('localpart')->get()
// : collect();
//
// $this->recipients = [['mail_user_id' => null, 'email' => null]];
//
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// }
//
//
// public function removeRecipientRow(int $index): void
// {
// unset($this->recipients[$index]);
// $this->recipients = array_values($this->recipients);
// $this->ensureAtLeastOneRow();
// $this->recomputeUi();
// }
//
// private function ensureAtLeastOneRow(): void
// {
// if (empty($this->recipients)) {
// $this->recipients = [['mail_user_id'=>null,'email'=>null]];
// }
// }
//
// private function recomputeUi(): void
// {
// $count = count($this->recipients);
//
// // Button „+ Empfänger“
// $this->canAddRecipient = $this->type === 'group' && $count < $this->maxGroupRecipients;
//
// // Sammle bereits gewählte interne Mailbox-IDs und externe E-Mails (normalisiert)
// $usedMailboxIds = [];
// $usedExternal = [];
//
// foreach ($this->recipients as $i => $r) {
// if (!empty($r['mail_user_id'])) $usedMailboxIds[] = (int)$r['mail_user_id'];
// if (!empty($r['email'])) $usedExternal[] = Str::lower(trim((string)$r['email']));
// }
//
// // pro Zeile: welche Mailbox-IDs sollen disabled sein (alle used außer die eigene)
// $this->disabledMailboxIdsByRow = [];
// $this->rowState = [];
// $this->rowDuplicateError = [];
//
// for ($i=0; $i<$count; $i++) {
// $myId = (int)($this->recipients[$i]['mail_user_id'] ?? 0);
// $myEmail = Str::lower(trim((string)($this->recipients[$i]['email'] ?? '')));
//
// $disabled = array_values(array_unique(array_filter($usedMailboxIds, fn($id) => $id && $id !== $myId)));
// $this->disabledMailboxIdsByRow[$i] = $disabled;
//
// $hasInternal = $myId > 0;
// $hasExternal = $myEmail !== '';
//
// $this->rowState[$i] = [
// 'disable_internal' => $hasExternal, // XOR
// 'disable_external' => $hasInternal, // XOR
// 'can_remove' => !($this->type === 'single' && $count === 1),
// ];
//
// // Duplikats-UI: wenn meine Zieladresse mehrfach vorkommt -> Fehlermeldung für diese Zeile
// if ($hasInternal && count(array_filter($usedMailboxIds, fn($id) => $id === $myId)) > 1) {
// $this->rowDuplicateError[$i] = 'Dieses Postfach ist bereits Empfänger.';
// }
// if ($hasExternal && count(array_filter($usedExternal, fn($e) => $e === $myEmail)) > 1) {
// $this->rowDuplicateError[$i] = 'Diese E-Mail ist bereits Empfänger.';
// }
// }
//
// $this->hasDuplicatesAndMarkUi();
// }
//
//// private function assertNoDuplicates(): void
//// {
//// // Ziel-Strings bilden: intern -> localpart@domain, extern -> E-Mail
//// $targets = [];
//// foreach ($this->recipients as $r) {
//// if (!empty($r['mail_user_id'])) {
//// $u = MailUser::find((int)$r['mail_user_id']);
//// if ($u && $this->domain) {
//// $targets[] = Str::lower($u->localpart.'@'.$this->domain->domain);
//// }
//// } elseif (!empty($r['email'])) {
//// $targets[] = Str::lower(trim((string)$r['email']));
//// }
//// }
//// $dupes = array_unique(array_diff_key($targets, array_unique($targets)));
//// if (!empty($dupes)) {
//// $this->addError('recipients', 'Doppelte Empfänger nicht erlaubt.');
//// throw new \RuntimeException('duplicates'); // brich Save clean ab
//// }
//// }
//
// private function hasDuplicatesAndMarkUi(): bool
// {
// // Ziel-String pro Zeile: intern => local@domain, extern => email
// $targets = []; // [i => 'office@pixio.at']
// $byValueCount = []; // 'office@pixio.at' => n
//
// $this->rowDuplicateError = []; // UI reset
//
// foreach ($this->recipients as $i => $r) {
// $val = null;
//
// if (!empty($r['mail_user_id'])) {
// $u = MailUser::find((int)$r['mail_user_id']);
// if ($u && $this->domain) {
// $val = mb_strtolower($u->localpart.'@'.$this->domain->domain);
// }
// } elseif (!empty($r['email'])) {
// $val = mb_strtolower(trim((string)$r['email']));
// }
//
// if ($val) {
// $targets[$i] = $val;
// $byValueCount[$val] = ($byValueCount[$val] ?? 0) + 1;
// }
// }
//
// $hasDupes = false;
// foreach ($targets as $i => $val) {
// if (($byValueCount[$val] ?? 0) > 1) {
// $this->rowDuplicateError[$i] = 'Dieser Empfänger ist bereits hinzugefügt.';
// $hasDupes = true;
// }
// }
//
// return $hasDupes;
// }
//
//
//
// public function save(): void
// {
// $this->validate($this->rules(), $this->messages());
//
// // XOR-Check Empfänger + Single/Group-Logik
// $rows = collect($this->recipients)
// ->map(fn($r) => [
// 'mail_user_id' => $r['mail_user_id'] ?: null,
// 'email' => isset($r['email']) && $r['email'] !== '' ? mb_strtolower(trim($r['email'])) : null,
// ])
// ->filter(fn($r) => $r['mail_user_id'] || $r['email'])
// ->values();
//
// if ($rows->isEmpty()) {
// $this->addError('recipients', 'Mindestens ein Empfänger erforderlich.');
// return;
// }
// if ($this->type === 'single' && $rows->count() !== 1) {
// $this->addError('recipients', 'Bei Single-Alias ist genau ein Empfänger erlaubt.');
// return;
// }
//
// foreach ($this->recipients as $i => $r) {
// if (empty($r['mail_user_id']) && empty($r['email'])) {
// $this->addError("recipients.$i", 'Wähle internes Postfach oder externe E-Mail.');
// return;
// }
// }
//
// if ($this->validateRecipientDuplicates()) {
// return; // freundlich abbrechen, keine Exception
// }
//
// // 4) Alias-Adresse vs. bestehende Mailboxen (siehe Teil B)
// if ($this->aliasConflictsWithMailbox()) {
// $this->addError('local', 'Diese Adresse ist bereits als Postfach vergeben.');
// return;
// }
//
//
// DB::transaction(function () use ($rows) {
// /** @var MailAlias $alias */
// $alias = MailAlias::updateOrCreate(
// ['id' => $this->aliasId],
// [
// 'domain_id' => $this->domainId,
// 'local' => $this->local,
// 'type' => $this->type,
// 'is_active' => $this->is_active,
// 'notes' => $this->notes,
// ]
// );
//
// // Empfänger neu schreiben (einfach & robust)
// $alias->recipients()->delete();
// foreach ($rows as $i => $r) {
// $alias->recipients()->create([
// 'mail_user_id' => $r['mail_user_id'],
// 'email' => $r['email'],
// 'position' => $i,
// ]);
// }
//
// $this->aliasId = $alias->id;
// });
//
// $this->dispatch('alias:' . ($this->aliasId ? 'updated' : 'created'));
// $this->dispatch('closeModal');
// }
//
// private function aliasConflictsWithMailbox(): bool
// {
// if (!$this->domainId || $this->local === '') return false;
//
// $local = Str::lower(trim($this->local));
//
// return MailUser::query()
// ->where('domain_id', $this->domainId)
// ->whereRaw('LOWER(localpart) = ?', [$local])
// ->exists();
// }
//
// protected function rules(): array
// {
// $occupied = MailUser::query()
// ->where('domain_id', $this->domainId)
// ->pluck('localpart')
// ->map(fn($l) => Str::lower($l))
// ->all();
//
// return [
// 'domainId' => ['required','exists:domains,id'],
// 'local' => [
// 'required',
// 'regex:/^[A-Za-z0-9._%+-]+$/',
// Rule::unique('mail_aliases','local')
// ->ignore($this->aliasId)
// ->where(fn($q) => $q->where('domain_id', $this->domainId)),
// Rule::notIn($occupied), // verhindert offensichtliche Kollisionen
// ],
// 'type' => ['required','in:single,group'],
// 'recipients' => ['array','min:1','max:'.($this->type==='single'?1:$this->maxGroupRecipients)],
// 'recipients.*.mail_user_id' => ['nullable','exists:mail_users,id'],
// 'recipients.*.email' => ['nullable','email:rfc'],
// ];
// }
//
//
// protected function messages(): array
// {
// return [
// 'local.not_in' => 'Diese Adresse ist bereits als Postfach vergeben.',
// 'local.unique' => 'Dieser Alias existiert in dieser Domain bereits.',
// 'local.regex' => 'Erlaubt sind Buchstaben, Zahlen und ._%+-',
// 'recipients.min' => 'Mindestens ein Empfänger ist erforderlich.',
// 'recipients.max' => $this->type === 'single'
// ? 'Bei „Single“ ist nur ein Empfänger zulässig.'
// : 'Maximal '.$this->maxGroupRecipients.' Empfänger erlaubt.',
// ];
// }
//
//
// public function render()
// {
// return view('livewire.ui.mail.modal.alias-form-modal', [
// 'domains' => Domain::where('is_system', false)->orderBy('domain')->get(['id','domain']),
// ]);
// }
//}