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

412 lines
14 KiB
PHP

<?php
namespace App\Livewire\Ui\Mail\Modal;
use App\Models\MailUser;
use App\Models\Domain;
use Illuminate\Support\Facades\Hash;
use Livewire\Attributes\On;
use LivewireUI\Modal\ModalComponent;
class MailboxEditModal extends ModalComponent
{
public int $mailboxId;
public ?MailUser $mailbox = null;
// Felder
public ?string $display_name = null;
public ?string $password = null;
public int $quota_mb = 0;
public ?int $rate_limit_per_hour = null;
public bool $is_active = true;
public bool $must_change_pw = true;
// UI
public string $email_readonly = '';
public string $quota_hint = '';
public bool $rate_limit_readonly = false;
public static function modalMaxWidth(): string
{
return 'lg';
}
public function mount(int $mailboxId): void
{
$this->mailboxId = $mailboxId;
$this->mailbox = MailUser::with('domain')->findOrFail($mailboxId);
// Felder vorbelegen
$this->display_name = $this->mailbox->display_name;
$this->quota_mb = (int)$this->mailbox->quota_mb;
$this->rate_limit_per_hour = $this->mailbox->rate_limit_per_hour;
$this->is_active = (bool)$this->mailbox->is_active;
$this->must_change_pw = (bool)$this->mailbox->must_change_pw;
$dom = $this->mailbox->domain;
$this->email_readonly = $this->mailbox->localpart . '@' . $dom->domain;
// Quota-Hinweis + Rate-Limit-Readonly
$this->buildHints($dom);
}
private function buildHints(Domain $d): void
{
// verbleibend inkl. der bisherigen Quota dieser Mailbox (damit Edit nicht sofort blockiert)
$usedWithoutThis = (int)$d->mailUsers()
->where('id', '!=', $this->mailbox->id)
->sum('quota_mb');
$remainingByTotal = is_null($d->total_quota_mb)
? null
: max(0, (int)$d->total_quota_mb - $usedWithoutThis);
$parts = [];
if (!is_null($d->max_quota_per_mailbox_mb)) $parts[] = "Max {$d->max_quota_per_mailbox_mb} MiB pro Postfach";
if (!is_null($remainingByTotal)) $parts[] = "Verbleibend jetzt: {$remainingByTotal} MiB";
if (!is_null($d->default_quota_mb)) $parts[] = "Standard: {$d->default_quota_mb} MiB";
$this->quota_hint = implode(' · ', $parts);
// Domain-Rate-Limit: Override?
if (!$d->rate_limit_override) {
$this->rate_limit_per_hour = $d->rate_limit_per_hour;
$this->rate_limit_readonly = true;
} else {
if (is_null($this->rate_limit_per_hour)) $this->rate_limit_per_hour = $d->rate_limit_per_hour;
$this->rate_limit_readonly = false;
}
}
protected function rules(): array
{
// defensiv: wenn mailbox oder domain noch nicht da → keine Caps
$d = $this->mailbox?->domain;
$maxPerMailbox = $d?->max_quota_per_mailbox_mb ?? PHP_INT_MAX;
if ($d) {
$usedWithoutThis = (int)$d->mailUsers()
->where('id', '!=', $this->mailbox->id)
->sum('quota_mb');
$remainingByTotal = is_null($d->total_quota_mb)
? PHP_INT_MAX
: max(0, (int)$d->total_quota_mb - $usedWithoutThis);
$cap = min($maxPerMailbox, $remainingByTotal);
} else {
$cap = PHP_INT_MAX;
}
return [
'display_name' => ['nullable', 'string', 'max:191'],
'password' => ['nullable', 'string', 'min:8'],
'quota_mb' => ['required', 'integer', 'min:0', 'max:' . $cap],
'rate_limit_per_hour' => ['nullable', 'integer', 'min:1'],
'is_active' => ['boolean'],
'must_change_pw' => ['boolean'],
];
}
#[On('mailbox:edit:save')]
public function save(): void
{
$this->validate();
$u = $this->mailbox; // schon geladen
$d = $u->domain;
// Speichern
$u->display_name = $this->display_name ?: null;
if (!empty($this->password)) {
$u->password_hash = Hash::make($this->password);
$u->must_change_pw = true;
}
$u->quota_mb = (int)$this->quota_mb;
$u->rate_limit_per_hour = $this->rate_limit_readonly ? $d->rate_limit_per_hour : $this->rate_limit_per_hour;
$u->is_active = (bool)$this->is_active;
$u->must_change_pw = (bool)$this->must_change_pw;
$u->save();
$mailbox = $u->localpart . '@' . $d->domain;
$this->dispatch('mailbox:updated');
$this->dispatch('closeModal');
$this->dispatch('toast',
type: 'done',
badge: 'Postfach',
title: 'Postfach aktualisiert',
text: 'Das Postfach <b>' . $mailbox . '</b> wurde erfolgreich aktualisiert.',
duration: 6000
);
}
public function render()
{
return view('livewire.ui.mail.modal.mailbox-edit-modal');
}
}
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\MailUser;
//use LivewireUI\Modal\ModalComponent;
//use Illuminate\Support\Facades\Hash;
//use Illuminate\Validation\Rule;
//
//class MailboxEditModal extends ModalComponent
//{
// // Eingangs-Argument (du rufst openMailboxEdit($id))
// public int $domainId; // = mailbox_id
//
// // Anzeige
// public string $email_display = ''; // readonly im UI
//
// // Editierbare Felder
// public ?string $display_name = null;
// public ?string $password = null; // leer => unverändert
// public int $quota_mb = 0;
// public ?int $rate_limit_per_hour = null;
// public bool $is_active = true;
//
// // Intern
// protected MailUser $mailbox;
//
// // Hinweise
// public string $quota_hint = '';
//
// public function mount(int $domainId): void
// {
// $this->domainId = $domainId;
//
// $this->mailbox = MailUser::query()
// ->with('domain:id,domain,total_quota_mb,max_quota_per_mailbox_mb,default_quota_mb')
// ->findOrFail($this->domainId);
//
// $this->email_display = $this->mailbox->localpart . '@' . $this->mailbox->domain->domain;
// $this->display_name = $this->mailbox->display_name;
// $this->quota_mb = (int)$this->mailbox->quota_mb;
// $this->rate_limit_per_hour = $this->mailbox->rate_limit_per_hour;
// $this->is_active = (bool)$this->mailbox->is_active;
//
// // Quota-Hinweis bauen
// $d = $this->mailbox->domain;
// $parts = [];
// if (!is_null($d->total_quota_mb)) {
// // verbleibend „nach Speichern“ kannst du bei Bedarf einsetzen, hier nur aktuell
// $parts[] = 'Verbleibend jetzt: ' . number_format((int)$d->total_quota_mb, 0, ',', '.') . ' MiB';
// }
// if (!is_null($d->max_quota_per_mailbox_mb)) $parts[] = 'Max ' . $d->max_quota_per_mailbox_mb . ' MiB pro Postfach';
// if (!is_null($d->default_quota_mb)) $parts[] = 'Standard: ' . $d->default_quota_mb . ' MiB';
// $this->quota_hint = implode(' · ', $parts);
// }
//
// protected function rules(): array
// {
// $d = $this->mailbox->domain;
//
// $maxPerMailbox = $d->max_quota_per_mailbox_mb ?: PHP_INT_MAX;
//
// return [
// 'display_name' => ['nullable', 'string', 'max:191'],
// 'password' => ['nullable', 'string', 'min:8'],
// 'quota_mb' => ['required', 'integer', 'min:0', 'max:' . $maxPerMailbox],
// 'rate_limit_per_hour' => ['nullable', 'integer', 'min:1'],
// 'is_active' => ['boolean'],
// ];
// }
//
// public function save(): void
// {
// $data = $this->validate();
//
// // speichern
// $this->mailbox->display_name = $data['display_name'] ?: null;
// if (!empty($data['password'])) {
// $this->mailbox->password_hash = Hash::make($data['password']);
// }
// $this->mailbox->quota_mb = (int)$data['quota_mb'];
// $this->mailbox->rate_limit_per_hour = $data['rate_limit_per_hour'];
// $this->mailbox->is_active = (bool)$data['is_active'];
// $this->mailbox->save();
//
// $this->dispatch('mailbox:updated');
// $this->dispatch('closeModal');
// $this->dispatch('toast', [
// 'state' => 'success',
// 'text' => 'Postfach wurde erfolgreich aktualisiert.',
// ]);
// }
//
// public static function modalMaxWidth(): string
// {
// return '4xl';
// }
//
// public function render()
// {
// return view('livewire.ui.mail.modal.mailbox-edit-modal');
// }
//}
//
//namespace App\Livewire\Ui\Mail\Modal;
//
//use App\Models\Domain;
//use App\Models\MailUser;
//use Illuminate\Support\Facades\Hash;
//use Illuminate\Validation\Rule;
//use LivewireUI\Modal\ModalComponent;
//
//class MailboxEditModal extends ModalComponent
//{
// public int $mailboxId;
//
// // read-only Anzeige
// public string $email = '';
//
// // editierbare Felder
// public ?string $display_name = null;
// public string $password = '';
// public int $quota_mb = 0;
// public ?int $rate_limit_per_hour = null;
// public bool $is_active = true;
//
// // Domain/Limits
// public int $domain_id;
// public ?int $limit_default_quota_mb = null;
// public ?int $limit_max_quota_per_mb = null; // pro Mailbox
// public ?int $limit_total_quota_mb = null; // gesamt (0/NULL = unbegrenzt)
// public ?int $limit_domain_rate_per_hour = null;
// public bool $allow_rate_limit_override = false;
//
// // Status/Ausgabe
// public int $domain_storage_used_mb = 0; // Summe Quotas aller Mailboxen
// public int $this_orig_quota_mb = 0; // Original der aktuellen Mailbox
// public string $quota_hint = '';
// public bool $rate_limit_readonly = false;
//
// public function mount(int $mailboxId): void
// {
// $u = MailUser::with('domain')->findOrFail($mailboxId);
// $d = $u->domain;
//
// $this->mailboxId = $u->id;
// $this->domain_id = $d->id;
//
// $this->email = $u->email;
// $this->display_name = $u->display_name;
// $this->quota_mb = (int)$u->quota_mb;
// $this->this_orig_quota_mb = (int)$u->quota_mb;
// $this->rate_limit_per_hour = $u->rate_limit_per_hour;
// $this->is_active = (bool)$u->is_active;
//
// // Limits aus Domain
// $agg = Domain::query()
// ->withSum('mailUsers as used_storage_mb', 'quota_mb')
// ->findOrFail($d->id);
//
// $this->limit_default_quota_mb = $d->default_quota_mb;
// $this->limit_max_quota_per_mb = $d->max_quota_per_mailbox_mb;
// $this->limit_total_quota_mb = $d->total_quota_mb; // 0 = unbegrenzt
// $this->limit_domain_rate_per_hour = $d->rate_limit_per_hour;
// $this->allow_rate_limit_override = (bool)$d->rate_limit_override;
//
// $this->domain_storage_used_mb = (int)($agg->used_storage_mb ?? 0);
//
// // Rate-Limit-Feld ggf. readonly machen
// if (!$this->allow_rate_limit_override) {
// $this->rate_limit_per_hour = $this->limit_domain_rate_per_hour;
// $this->rate_limit_readonly = true;
// }
//
// $this->buildQuotaHint();
// }
//
// protected function rules(): array
// {
// // „Rest gesamt“ = total - (used - this_orig) (wir dürfen die alte Quota dieser Mailbox neu verteilen)
// $remainingByTotal = ($this->limit_total_quota_mb === null || $this->limit_total_quota_mb === 0)
// ? PHP_INT_MAX
// : max(0, (int)$this->limit_total_quota_mb - max(0, (int)$this->domain_storage_used_mb - $this->this_orig_quota_mb));
//
// $maxPerMailbox = $this->limit_max_quota_per_mb ?? PHP_INT_MAX;
// $cap = min($maxPerMailbox, $remainingByTotal);
//
// return [
// 'display_name' => ['nullable','string','max:191'],
// 'password' => ['nullable','string','min:8'],
// 'quota_mb' => ['required','integer','min:0','max:'.$cap],
// 'rate_limit_per_hour' => ['nullable','integer','min:1'],
// 'is_active' => ['boolean'],
// ];
// }
//
// public function updatedQuotaMb(): void
// {
// $this->buildQuotaHint();
// }
//
// private function buildQuotaHint(): void
// {
// $parts = [];
// if (!is_null($this->limit_total_quota_mb) && $this->limit_total_quota_mb > 0) {
// $usedMinusThis = max(0, (int)$this->domain_storage_used_mb - $this->this_orig_quota_mb);
// $nowRemaining = max(0, (int)$this->limit_total_quota_mb - $usedMinusThis);
// $after = max(0, (int)$this->limit_total_quota_mb - $usedMinusThis - max(0,(int)$this->quota_mb));
//
// $parts[] = "Verbleibend jetzt: {$nowRemaining} MiB";
// $parts[] = "nach Speichern: {$after} MiB";
// }
// if (!is_null($this->limit_max_quota_per_mb)) {
// $parts[] = "Max {$this->limit_max_quota_per_mb} MiB pro Postfach";
// }
// if (!is_null($this->limit_default_quota_mb)) {
// $parts[] = "Standard: {$this->limit_default_quota_mb} MiB";
// }
// $this->quota_hint = implode(' · ', $parts);
// }
//
// public function save(): void
// {
// $data = $this->validate();
//
// // Falls Override verboten ist → Domain-Wert erzwingen
// if (!$this->allow_rate_limit_override) {
// $data['rate_limit_per_hour'] = $this->limit_domain_rate_per_hour;
// }
//
// $u = MailUser::findOrFail($this->mailboxId);
//
// // Passwort optional ändern
// if (!empty($data['password'] ?? '')) {
// $u->password_hash = Hash::make($data['password']);
// }
//
// $u->display_name = $data['display_name'] ?? null;
// $u->quota_mb = (int)$data['quota_mb'];
// $u->rate_limit_per_hour = $data['rate_limit_per_hour'] ?? null;
// $u->is_active = (bool)$data['is_active'];
// $u->save();
//
// $this->dispatch('mailbox:updated');
// $this->dispatch('closeModal');
// $this->dispatch('toast',
// type: 'done',
// badge: 'Mailbox',
// title: 'Postfach aktualisiert',
// text: 'Die Änderungen wurden gespeichert.',
// duration: 4000,
// );
// }
//
// public static function modalMaxWidth(): string
// {
// return '3xl';
// }
//
// public function render()
// {
// return view('livewire.ui.mail.modal.mailbox-edit-modal');
// }
//}