parent
57b01654cc
commit
50f1166fa3
|
|
@ -13,128 +13,98 @@ use RecursiveIteratorIterator;
|
||||||
class UpdateMailboxStats extends Command
|
class UpdateMailboxStats extends Command
|
||||||
{
|
{
|
||||||
protected $signature = 'mail:update-stats {--user=}';
|
protected $signature = 'mail:update-stats {--user=}';
|
||||||
protected $description = 'Aktualisiert Quota & Nachrichtenzahl (Settings/Redis; ohne MailUser-DB-Felder).';
|
protected $description = 'Aktualisiert Quota & Nachrichtenzahl (Settings/Redis; ohne DB-Spalten).';
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$log = Log::channel('mailstats');
|
$log = Log::channel('mailstats');
|
||||||
|
|
||||||
$onlyUser = trim((string)$this->option('user')) ?: null;
|
$onlyUser = trim((string)$this->option('user')) ?: null;
|
||||||
$started = microtime(true);
|
$t0 = microtime(true);
|
||||||
|
|
||||||
$q = MailUser::query()
|
// Basis-Query: nur aktive, keine System-Mailboxen und keine System-Domains
|
||||||
->with('domain:id,domain,is_system')
|
$base = MailUser::query()
|
||||||
|
->select(['id', 'domain_id', 'localpart', 'email', 'is_active', 'is_system'])
|
||||||
|
->with(['domain:id,domain,is_system'])
|
||||||
->where('is_active', true)
|
->where('is_active', true)
|
||||||
->where('is_system', false) // keine System-Mailboxen
|
->where('is_system', false)
|
||||||
->whereHas('domain', fn($d) => $d->where('is_system', false)); // keine Systemdomains
|
->whereHas('domain', fn($d) => $d->where('is_system', false));
|
||||||
|
|
||||||
if ($onlyUser) {
|
if ($onlyUser) {
|
||||||
$q->where('email', $onlyUser);
|
$base->where('email', $onlyUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
$users = $q->get();
|
|
||||||
|
|
||||||
$log->info('mail:update-stats START', [
|
|
||||||
'only' => $onlyUser,
|
|
||||||
'users' => $users->count(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($users->isEmpty()) {
|
|
||||||
$this->warn('Keine passenden Mailboxen gefunden.');
|
|
||||||
$log->info('mail:update-stats DONE (no users)', ['ms' => (int)((microtime(true) - $started) * 1000)]);
|
|
||||||
return self::SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
$changed = 0;
|
|
||||||
$checked = 0;
|
$checked = 0;
|
||||||
|
$changed = 0;
|
||||||
|
|
||||||
foreach ($users as $u) {
|
$log->info('mail:update-stats START', ['only' => $onlyUser]);
|
||||||
$checked++;
|
|
||||||
|
|
||||||
// Email robust ermitteln
|
$base->orderBy('id')->chunkById(200, function ($users) use (&$checked, &$changed, $log) {
|
||||||
$raw = (string)($u->getRawOriginal('email') ?? '');
|
foreach ($users as $u) {
|
||||||
$email = $raw !== '' ? $raw : ($u->email ?? $u->address ?? null);
|
$checked++;
|
||||||
|
|
||||||
if (!is_string($email) || !preg_match('/^[^@\s]+@[^@\s]+\.[^@\s]+$/', $email)) {
|
// Email robust bestimmen (raw -> accessor -> zusammengesetzt)
|
||||||
// nur debug – vermeidet Spam
|
$raw = (string)($u->getRawOriginal('email') ?? '');
|
||||||
$log->debug('skip invalid email', ['user_id' => $u->id, 'raw' => $raw, 'computed' => $email]);
|
$email = $raw !== '' ? $raw : ($u->email ?? $u->address ?? null);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
[$local, $domain] = explode('@', $email, 2);
|
if (!is_string($email) || !preg_match('/^[^@\s]+@[^@\s]+\.[^@\s]+$/', $email)) {
|
||||||
$maildir = "/var/mail/vhosts/{$domain}/{$local}";
|
// still – kein Log-Spam
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Größe (Dateisystem)
|
[$local, $domain] = explode('@', $email, 2);
|
||||||
$usedBytes = 0;
|
$maildir = "/var/mail/vhosts/{$domain}/{$local}";
|
||||||
if (is_dir($maildir)) {
|
|
||||||
$it = new RecursiveIteratorIterator(
|
// Größe in Bytes (rekursiv)
|
||||||
new RecursiveDirectoryIterator($maildir, \FilesystemIterator::SKIP_DOTS)
|
$usedBytes = 0;
|
||||||
);
|
if (is_dir($maildir)) {
|
||||||
foreach ($it as $f) {
|
$it = new RecursiveIteratorIterator(
|
||||||
if ($f->isFile()) {
|
new RecursiveDirectoryIterator($maildir, \FilesystemIterator::SKIP_DOTS)
|
||||||
$usedBytes += $f->getSize();
|
);
|
||||||
|
foreach ($it as $f) {
|
||||||
|
if ($f->isFile()) $usedBytes += $f->getSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Message-Count
|
||||||
|
$messageCount = $this->countViaDoveadm($email);
|
||||||
|
if ($messageCount === null) {
|
||||||
|
$messageCount = $this->countViaFilesystem($maildir);
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = "mailbox.{$email}";
|
||||||
|
$prev = (array)(Setting::get($key, []) ?: []);
|
||||||
|
$new = [
|
||||||
|
'used_bytes' => (int)$usedBytes,
|
||||||
|
'message_count' => (int)$messageCount,
|
||||||
|
'updated_at' => now()->toDateTimeString(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (($prev['used_bytes'] ?? null) !== $new['used_bytes']
|
||||||
|
|| ($prev['message_count'] ?? null) !== $new['message_count']) {
|
||||||
|
Setting::set($key, $new);
|
||||||
|
$changed++;
|
||||||
|
|
||||||
|
// kurze Ausgabe & Info-Log NUR bei Änderung
|
||||||
|
$this->line(sprintf("%-35s %7.1f MiB %5d msgs",
|
||||||
|
$email, $usedBytes / 1048576, $messageCount));
|
||||||
|
$log->info('updated', ['email' => $email, 'used_bytes' => $new['used_bytes'], 'message_count' => $new['message_count']]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Nachrichten zählen
|
$ms = (int)((microtime(true) - $t0) * 1000);
|
||||||
$messageCount = $this->countViaDoveadm($email);
|
$log->info('mail:update-stats DONE', compact('checked', 'changed', 'ms'));
|
||||||
if ($messageCount === null) {
|
|
||||||
$messageCount = $this->countViaFilesystem($maildir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nur bei Änderungen persistieren + loggen
|
|
||||||
$key = "mailbox.{$email}";
|
|
||||||
$prev = Setting::get($key, null) ?: [];
|
|
||||||
|
|
||||||
$new = [
|
|
||||||
'used_bytes' => (int)$usedBytes,
|
|
||||||
'message_count' => (int)$messageCount,
|
|
||||||
'updated_at' => now()->toDateTimeString(),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (
|
|
||||||
!is_array($prev) ||
|
|
||||||
($prev['used_bytes'] ?? null) !== $new['used_bytes'] ||
|
|
||||||
($prev['message_count'] ?? null) !== $new['message_count']
|
|
||||||
) {
|
|
||||||
Setting::set($key, $new);
|
|
||||||
$changed++;
|
|
||||||
|
|
||||||
// kurze, nützliche Info – nur bei Änderung
|
|
||||||
$this->line(sprintf("%-35s %7.1f MiB %5d msgs",
|
|
||||||
$email, $usedBytes / 1024 / 1024, $messageCount));
|
|
||||||
|
|
||||||
$log->info('updated', [
|
|
||||||
'email' => $email,
|
|
||||||
'used_bytes' => $new['used_bytes'],
|
|
||||||
'message_count' => $new['message_count'],
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
// keine Änderung → kein Info-Log
|
|
||||||
$log->debug('unchanged', ['email' => $email]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ms = (int)((microtime(true) - $started) * 1000);
|
|
||||||
$log->info('mail:update-stats DONE', [
|
|
||||||
'checked' => $checked,
|
|
||||||
'changed' => $changed,
|
|
||||||
'ms' => $ms,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->info('Mailbox-Statistiken aktualisiert.');
|
$this->info('Mailbox-Statistiken aktualisiert.');
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function countViaDoveadm(string $email): ?int
|
private function countViaDoveadm(string $email): ?int
|
||||||
{
|
{
|
||||||
$cmd = "sudo -n -u vmail /usr/bin/doveadm -f tab mailbox status -u "
|
$cmd = "sudo -n -u vmail /usr/bin/doveadm -f tab mailbox status -u "
|
||||||
. escapeshellarg($email) . " messages INBOX 2>&1";
|
. escapeshellarg($email) . " messages INBOX 2>&1";
|
||||||
$out = [];
|
$out = [];
|
||||||
$rc = 0;
|
$rc = 0;
|
||||||
exec($cmd, $out, $rc);
|
exec($cmd, $out, $rc);
|
||||||
|
|
||||||
if ($rc !== 0) return null;
|
if ($rc !== 0) return null;
|
||||||
|
|
||||||
foreach ($out as $line) {
|
foreach ($out as $line) {
|
||||||
|
|
@ -145,7 +115,7 @@ class UpdateMailboxStats extends Command
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function countViaFilesystem(string $maildir): int
|
private function countViaFilesystem(string $maildir): int
|
||||||
{
|
{
|
||||||
$n = 0;
|
$n = 0;
|
||||||
foreach (['cur', 'new'] as $sub) {
|
foreach (['cur', 'new'] as $sub) {
|
||||||
|
|
@ -163,6 +133,168 @@ class UpdateMailboxStats extends Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//namespace App\Console\Commands;
|
||||||
|
//
|
||||||
|
//use App\Models\MailUser;
|
||||||
|
//use App\Models\Setting;
|
||||||
|
//use Illuminate\Console\Command;
|
||||||
|
//use Illuminate\Support\Facades\Log;
|
||||||
|
//use RecursiveDirectoryIterator;
|
||||||
|
//use RecursiveIteratorIterator;
|
||||||
|
//
|
||||||
|
//class UpdateMailboxStats extends Command
|
||||||
|
//{
|
||||||
|
// protected $signature = 'mail:update-stats {--user=}';
|
||||||
|
// protected $description = 'Aktualisiert Quota & Nachrichtenzahl (Settings/Redis; ohne MailUser-DB-Felder).';
|
||||||
|
//
|
||||||
|
// public function handle(): int
|
||||||
|
// {
|
||||||
|
// $log = Log::channel('mailstats');
|
||||||
|
//
|
||||||
|
// $onlyUser = trim((string)$this->option('user')) ?: null;
|
||||||
|
// $started = microtime(true);
|
||||||
|
//
|
||||||
|
// $q = MailUser::query()
|
||||||
|
// ->with('domain:id,domain,is_system')
|
||||||
|
// ->where('is_active', true)
|
||||||
|
// ->where('is_system', false) // keine System-Mailboxen
|
||||||
|
// ->whereHas('domain', fn($d) => $d->where('is_system', false)); // keine Systemdomains
|
||||||
|
//
|
||||||
|
// if ($onlyUser) {
|
||||||
|
// $q->where('email', $onlyUser);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $users = $q->get();
|
||||||
|
//
|
||||||
|
// $log->info('mail:update-stats START', [
|
||||||
|
// 'only' => $onlyUser,
|
||||||
|
// 'users' => $users->count(),
|
||||||
|
// ]);
|
||||||
|
//
|
||||||
|
// if ($users->isEmpty()) {
|
||||||
|
// $this->warn('Keine passenden Mailboxen gefunden.');
|
||||||
|
// $log->info('mail:update-stats DONE (no users)', ['ms' => (int)((microtime(true) - $started) * 1000)]);
|
||||||
|
// return self::SUCCESS;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $changed = 0;
|
||||||
|
// $checked = 0;
|
||||||
|
//
|
||||||
|
// foreach ($users as $u) {
|
||||||
|
// $checked++;
|
||||||
|
//
|
||||||
|
// // Email robust ermitteln
|
||||||
|
// $raw = (string)($u->getRawOriginal('email') ?? '');
|
||||||
|
// $email = $raw !== '' ? $raw : ($u->email ?? $u->address ?? null);
|
||||||
|
//
|
||||||
|
// if (!is_string($email) || !preg_match('/^[^@\s]+@[^@\s]+\.[^@\s]+$/', $email)) {
|
||||||
|
// // nur debug – vermeidet Spam
|
||||||
|
// $log->debug('skip invalid email', ['user_id' => $u->id, 'raw' => $raw, 'computed' => $email]);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// [$local, $domain] = explode('@', $email, 2);
|
||||||
|
// $maildir = "/var/mail/vhosts/{$domain}/{$local}";
|
||||||
|
//
|
||||||
|
// // Größe (Dateisystem)
|
||||||
|
// $usedBytes = 0;
|
||||||
|
// if (is_dir($maildir)) {
|
||||||
|
// $it = new RecursiveIteratorIterator(
|
||||||
|
// new RecursiveDirectoryIterator($maildir, \FilesystemIterator::SKIP_DOTS)
|
||||||
|
// );
|
||||||
|
// foreach ($it as $f) {
|
||||||
|
// if ($f->isFile()) {
|
||||||
|
// $usedBytes += $f->getSize();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Nachrichten zählen
|
||||||
|
// $messageCount = $this->countViaDoveadm($email);
|
||||||
|
// if ($messageCount === null) {
|
||||||
|
// $messageCount = $this->countViaFilesystem($maildir);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Nur bei Änderungen persistieren + loggen
|
||||||
|
// $key = "mailbox.{$email}";
|
||||||
|
// $prev = Setting::get($key, null) ?: [];
|
||||||
|
//
|
||||||
|
// $new = [
|
||||||
|
// 'used_bytes' => (int)$usedBytes,
|
||||||
|
// 'message_count' => (int)$messageCount,
|
||||||
|
// 'updated_at' => now()->toDateTimeString(),
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// if (
|
||||||
|
// !is_array($prev) ||
|
||||||
|
// ($prev['used_bytes'] ?? null) !== $new['used_bytes'] ||
|
||||||
|
// ($prev['message_count'] ?? null) !== $new['message_count']
|
||||||
|
// ) {
|
||||||
|
// Setting::set($key, $new);
|
||||||
|
// $changed++;
|
||||||
|
//
|
||||||
|
// // kurze, nützliche Info – nur bei Änderung
|
||||||
|
// $this->line(sprintf("%-35s %7.1f MiB %5d msgs",
|
||||||
|
// $email, $usedBytes / 1024 / 1024, $messageCount));
|
||||||
|
//
|
||||||
|
// $log->info('updated', [
|
||||||
|
// 'email' => $email,
|
||||||
|
// 'used_bytes' => $new['used_bytes'],
|
||||||
|
// 'message_count' => $new['message_count'],
|
||||||
|
// ]);
|
||||||
|
// } else {
|
||||||
|
// // keine Änderung → kein Info-Log
|
||||||
|
// $log->debug('unchanged', ['email' => $email]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// $ms = (int)((microtime(true) - $started) * 1000);
|
||||||
|
// $log->info('mail:update-stats DONE', [
|
||||||
|
// 'checked' => $checked,
|
||||||
|
// 'changed' => $changed,
|
||||||
|
// 'ms' => $ms,
|
||||||
|
// ]);
|
||||||
|
//
|
||||||
|
// $this->info('Mailbox-Statistiken aktualisiert.');
|
||||||
|
// return self::SUCCESS;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected function countViaDoveadm(string $email): ?int
|
||||||
|
// {
|
||||||
|
// $cmd = "sudo -n -u vmail /usr/bin/doveadm -f tab mailbox status -u "
|
||||||
|
// . escapeshellarg($email) . " messages INBOX 2>&1";
|
||||||
|
// $out = [];
|
||||||
|
// $rc = 0;
|
||||||
|
// exec($cmd, $out, $rc);
|
||||||
|
//
|
||||||
|
// if ($rc !== 0) return null;
|
||||||
|
//
|
||||||
|
// foreach ($out as $line) {
|
||||||
|
// if (preg_match('/^\s*INBOX\s+(\d+)\s*$/i', trim($line), $m)) {
|
||||||
|
// return (int)$m[1];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected function countViaFilesystem(string $maildir): int
|
||||||
|
// {
|
||||||
|
// $n = 0;
|
||||||
|
// foreach (['cur', 'new'] as $sub) {
|
||||||
|
// $dir = "{$maildir}/{$sub}";
|
||||||
|
// if (!is_dir($dir)) continue;
|
||||||
|
// $h = opendir($dir);
|
||||||
|
// if (!$h) continue;
|
||||||
|
// while (($fn = readdir($h)) !== false) {
|
||||||
|
// if ($fn === '.' || $fn === '..' || $fn[0] === '.') continue;
|
||||||
|
// $n++;
|
||||||
|
// }
|
||||||
|
// closedir($h);
|
||||||
|
// }
|
||||||
|
// return $n;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
//namespace App\Console\Commands;
|
//namespace App\Console\Commands;
|
||||||
//
|
//
|
||||||
//use App\Models\MailUser;
|
//use App\Models\MailUser;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ namespace App\Livewire\Ui\Mail;
|
||||||
use App\Models\Domain;
|
use App\Models\Domain;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Livewire\Attributes\On;
|
use Livewire\Attributes\On;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
@ -27,15 +26,13 @@ class MailboxList extends Component
|
||||||
#[On('focus:domain')]
|
#[On('focus:domain')]
|
||||||
public function focusDomain(int $id): void
|
public function focusDomain(int $id): void
|
||||||
{
|
{
|
||||||
// z. B. Domain nach oben holen / scrollen / highlighten
|
// optional: Domain hervorheben
|
||||||
// oder direkt den "+ Postfach" Dialog:
|
|
||||||
// $this->openMailboxCreate($id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[On('focus:user')]
|
#[On('focus:user')]
|
||||||
public function focusUser(int $id): void
|
public function focusUser(int $id): void
|
||||||
{
|
{
|
||||||
// später: Benutzerseite / Filter setzen ...
|
// optional
|
||||||
}
|
}
|
||||||
|
|
||||||
public function openMailboxCreate(int $domainId): void
|
public function openMailboxCreate(int $domainId): void
|
||||||
|
|
@ -49,126 +46,89 @@ class MailboxList extends Component
|
||||||
{
|
{
|
||||||
// $domainId == mailbox_id
|
// $domainId == mailbox_id
|
||||||
$this->dispatch('openModal', component: 'ui.mail.modal.mailbox-edit-modal', arguments: [
|
$this->dispatch('openModal', component: 'ui.mail.modal.mailbox-edit-modal', arguments: [
|
||||||
$domainId, // <— nur der Wert, kein Key!
|
$domainId,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function openMailboxDelete(int $domainId): void
|
public function openMailboxDelete(int $domainId): void
|
||||||
{
|
{
|
||||||
$this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [
|
$this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [
|
||||||
$domainId, // <— nur der Wert, kein Key!
|
$domainId,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateMailboxStats()
|
public function updateMailboxStats(): void
|
||||||
{
|
{
|
||||||
$started = microtime(true);
|
Artisan::call('mail:update-stats');
|
||||||
|
|
||||||
Log::channel('mailstats')->info('UI: updateMailboxStats() geklickt', [
|
|
||||||
'actor' => 'web',
|
|
||||||
'ip' => request()->ip() ?? null,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Command ausführen
|
|
||||||
$rc = Artisan::call('mail:update-stats');
|
|
||||||
$output = Artisan::output();
|
|
||||||
|
|
||||||
Log::channel('mailstats')->info('UI: Command beendet', [
|
|
||||||
'rc' => $rc,
|
|
||||||
'ms' => (int)((microtime(true) - $started) * 1000),
|
|
||||||
'output' => trim($output),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// UI auffrischen
|
|
||||||
$this->dispatch('$refresh');
|
|
||||||
|
|
||||||
// Ergebnis toaster
|
|
||||||
$this->dispatch('toast',
|
|
||||||
type: $rc === 0 ? 'done' : 'warn',
|
|
||||||
badge: 'Mailbox',
|
|
||||||
title: $rc === 0 ? 'Mailbox aktualisiert' : 'Aktualisierung fehlgeschlagen',
|
|
||||||
text: $rc === 0 ? 'Statistiken wurden aktualisiert.' : 'Siehe logs/mailstats.log',
|
|
||||||
duration: 6000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function updateMailboxStatsOne(string $email)
|
|
||||||
{
|
|
||||||
Artisan::call('mail:update-stats', ['--user' => $email]);
|
|
||||||
$this->dispatch('$refresh');
|
$this->dispatch('$refresh');
|
||||||
$this->dispatch('toast',
|
$this->dispatch('toast',
|
||||||
type: 'done',
|
type: 'done',
|
||||||
badge: 'Mailbox',
|
badge: 'Mailbox',
|
||||||
title: 'Mailbox aktualisiert',
|
title: 'Mailbox aktualisiert',
|
||||||
text: 'Die Mailbox-Statistiken wurden aktualisiert.',
|
text: 'Die Mailbox-Statistiken wurden aktualisiert.',
|
||||||
duration: 6000
|
duration: 6000,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$system = Domain::query()->where('is_system', true)->first();
|
$system = Domain::query()->where('is_system', true)->first();
|
||||||
$term = trim($this->search);
|
$term = trim($this->search);
|
||||||
$hasTerm = $term !== '';
|
$hasTerm = $term !== '';
|
||||||
$needle = '%'.str_replace(['%','_'], ['\%','\_'], $term).'%'; // LIKE-sicher
|
$needle = '%' . str_replace(['%', '_'], ['\%', '\_'], $term) . '%';
|
||||||
|
|
||||||
$domains = Domain::query()
|
$domains = Domain::query()
|
||||||
->when($system, fn ($q) => $q->whereKeyNot($system->id))
|
->when($system, fn($q) => $q->whereKeyNot($system->id))
|
||||||
|
|
||||||
// Domain selbst ODER MailUser müssen matchen
|
|
||||||
->when($hasTerm, function ($q) use ($needle) {
|
->when($hasTerm, function ($q) use ($needle) {
|
||||||
$q->where(function ($w) use ($needle) {
|
$q->where(function ($w) use ($needle) {
|
||||||
$w->where('domain', 'like', $needle)
|
$w->where('domain', 'like', $needle)
|
||||||
->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle));
|
->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle));
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
->withCount(['mailUsers'])
|
->withCount(['mailUsers'])
|
||||||
|
|
||||||
// Relationen zunächst ggf. gefiltert laden
|
|
||||||
->with([
|
->with([
|
||||||
'mailUsers' => function ($q) use ($hasTerm, $needle) {
|
'mailUsers' => function ($q) use ($hasTerm, $needle) {
|
||||||
if ($hasTerm) $q->where('localpart', 'like', $needle);
|
if ($hasTerm) {
|
||||||
|
$q->where('localpart', 'like', $needle);
|
||||||
|
}
|
||||||
$q->orderBy('localpart');
|
$q->orderBy('localpart');
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
->orderBy('domain')
|
->orderBy('domain')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Wenn der Domainname selbst matched → alle Mailboxen/Aliasse vollständig nachladen
|
|
||||||
if ($hasTerm) {
|
if ($hasTerm) {
|
||||||
$lower = Str::lower($term);
|
$lower = Str::lower($term);
|
||||||
foreach ($domains as $d) {
|
foreach ($domains as $d) {
|
||||||
if (Str::contains(Str::lower($d->domain), $lower)) {
|
if (Str::contains(Str::lower($d->domain), $lower)) {
|
||||||
$d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get());
|
$d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get());
|
||||||
$d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get());
|
$d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vorbereitung für Blade
|
// ---- Anzeige vorbereiten (mit korrekter Prozent-Berechnung) ----
|
||||||
foreach ($domains as $d) {
|
foreach ($domains as $d) {
|
||||||
$prepared = [];
|
$prepared = [];
|
||||||
$domainActive = (bool)($d->is_active ?? true);
|
$domainActive = (bool)($d->is_active ?? true);
|
||||||
|
|
||||||
foreach ($d->mailUsers as $u) {
|
foreach ($d->mailUsers as $u) {
|
||||||
$email = trim($u->email ?? '') !== ''
|
// Stats aus Settings (Redis → DB Fallback)
|
||||||
? $u->email
|
$stats = Setting::get("mailbox.{$u->email}", []);
|
||||||
: ($u->localpart !== '' ? ($u->localpart.'@'.$d->domain) : null);
|
$usedBytes = (int)($stats['used_bytes'] ?? ($u->used_bytes ?? 0));
|
||||||
|
$messageCount = (int)($stats['message_count'] ?? ($u->message_count ?? 0));
|
||||||
|
|
||||||
$stats = $email ? Setting::get("mailbox.$email") : null;
|
// Anzeige in MiB (nur fürs UI runden)
|
||||||
|
$usedMiB = (float)round($usedBytes / 1048576, 2);
|
||||||
|
$quotaMiB = (int)($u->quota_mb ?? 0);
|
||||||
|
|
||||||
$usedBytes = is_array($stats) && isset($stats['used_bytes']) ? (int)$stats['used_bytes'] : (int)($u->used_bytes ?? 0);
|
// Prozent aus Bytes/Quota (ohne Vorab-Rundung auf MiB!)
|
||||||
$messageCount = is_array($stats) && isset($stats['message_count']) ? (int)$stats['message_count'] : (int)($u->message_count ?? 0);
|
$usage = $quotaMiB > 0
|
||||||
|
? min(100, (int)round($usedBytes / ($quotaMiB * 1048576) * 100))
|
||||||
$usedMB = (int) round($usedBytes / 1024 / 1024);
|
: 0;
|
||||||
$quota = (int)($u->quota_mb ?? 0);
|
|
||||||
$usage = $quota > 0 ? min(100, (int) round($usedMB / max(1, $quota) * 100)) : 0;
|
|
||||||
|
|
||||||
$mailboxActive = (bool)($u->is_active ?? true);
|
$mailboxActive = (bool)($u->is_active ?? true);
|
||||||
$effective = $domainActive && $mailboxActive;
|
$effective = $domainActive && $mailboxActive;
|
||||||
|
|
||||||
$reason = null;
|
$reason = null;
|
||||||
if (!$effective) {
|
if (!$effective) {
|
||||||
|
|
@ -177,15 +137,15 @@ class MailboxList extends Component
|
||||||
}
|
}
|
||||||
|
|
||||||
$prepared[] = [
|
$prepared[] = [
|
||||||
'id' => $u->id,
|
'id' => $u->id,
|
||||||
'localpart' => (string)$u->localpart,
|
'localpart' => (string)$u->localpart,
|
||||||
'quota_mb' => $quota,
|
'quota_mb' => $quotaMiB,
|
||||||
'usage_percent' => $usage,
|
'used_mb' => $usedMiB,
|
||||||
'used_mb' => $usedMB, // MiB fürs UI
|
'usage_percent' => $usage,
|
||||||
'message_count' => $messageCount,
|
'message_count' => $messageCount,
|
||||||
'is_active' => $mailboxActive,
|
'is_active' => $mailboxActive,
|
||||||
'is_effective_active' => $effective,
|
'is_effective_active' => $effective,
|
||||||
'inactive_reason' => $reason,
|
'inactive_reason' => $reason,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,9 +154,116 @@ class MailboxList extends Component
|
||||||
|
|
||||||
return view('livewire.ui.mail.mailbox-list', [
|
return view('livewire.ui.mail.mailbox-list', [
|
||||||
'domains' => $domains,
|
'domains' => $domains,
|
||||||
'system' => $this->showSystemCard ? $system : null,
|
'system' => $this->showSystemCard ? $system : null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//namespace App\Livewire\Ui\Mail;
|
||||||
|
//
|
||||||
|
//use App\Models\Domain;
|
||||||
|
//use App\Models\Setting;
|
||||||
|
//use Illuminate\Support\Facades\Artisan;
|
||||||
|
//use Illuminate\Support\Facades\Log;
|
||||||
|
//use Illuminate\Support\Str;
|
||||||
|
//use Livewire\Attributes\On;
|
||||||
|
//use Livewire\Component;
|
||||||
|
//
|
||||||
|
//class MailboxList extends Component
|
||||||
|
//{
|
||||||
|
// public string $search = '';
|
||||||
|
// public bool $showSystemCard = false;
|
||||||
|
//
|
||||||
|
// #[On('mailbox:updated')]
|
||||||
|
// #[On('mailbox:deleted')]
|
||||||
|
// #[On('mailbox:created')]
|
||||||
|
// public function refreshMailboxList(): void
|
||||||
|
// {
|
||||||
|
// $this->dispatch('$refresh');
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[On('focus:domain')]
|
||||||
|
// public function focusDomain(int $id): void
|
||||||
|
// {
|
||||||
|
// // z. B. Domain nach oben holen / scrollen / highlighten
|
||||||
|
// // oder direkt den "+ Postfach" Dialog:
|
||||||
|
// // $this->openMailboxCreate($id);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[On('focus:user')]
|
||||||
|
// public function focusUser(int $id): void
|
||||||
|
// {
|
||||||
|
// // später: Benutzerseite / Filter setzen ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public function openMailboxCreate(int $domainId): void
|
||||||
|
// {
|
||||||
|
// $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-create-modal', arguments: [
|
||||||
|
// 'domainId' => $domainId,
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public function openMailboxEdit(int $domainId): void
|
||||||
|
// {
|
||||||
|
// // $domainId == mailbox_id
|
||||||
|
// $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-edit-modal', arguments: [
|
||||||
|
// $domainId, // <— nur der Wert, kein Key!
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public function openMailboxDelete(int $domainId): void
|
||||||
|
// {
|
||||||
|
// $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [
|
||||||
|
// $domainId, // <— nur der Wert, kein Key!
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public function updateMailboxStats()
|
||||||
|
// {
|
||||||
|
// $started = microtime(true);
|
||||||
|
//
|
||||||
|
// Log::channel('mailstats')->info('UI: updateMailboxStats() geklickt', [
|
||||||
|
// 'actor' => 'web',
|
||||||
|
// 'ip' => request()->ip() ?? null,
|
||||||
|
// ]);
|
||||||
|
//
|
||||||
|
// // Command ausführen
|
||||||
|
// $rc = Artisan::call('mail:update-stats');
|
||||||
|
// $output = Artisan::output();
|
||||||
|
//
|
||||||
|
// Log::channel('mailstats')->info('UI: Command beendet', [
|
||||||
|
// 'rc' => $rc,
|
||||||
|
// 'ms' => (int)((microtime(true) - $started) * 1000),
|
||||||
|
// 'output' => trim($output),
|
||||||
|
// ]);
|
||||||
|
//
|
||||||
|
// // UI auffrischen
|
||||||
|
// $this->dispatch('$refresh');
|
||||||
|
//
|
||||||
|
// // Ergebnis toaster
|
||||||
|
// $this->dispatch('toast',
|
||||||
|
// type: $rc === 0 ? 'done' : 'warn',
|
||||||
|
// badge: 'Mailbox',
|
||||||
|
// title: $rc === 0 ? 'Mailbox aktualisiert' : 'Aktualisierung fehlgeschlagen',
|
||||||
|
// text: $rc === 0 ? 'Statistiken wurden aktualisiert.' : 'Siehe logs/mailstats.log',
|
||||||
|
// duration: 6000,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// public function updateMailboxStatsOne(string $email)
|
||||||
|
// {
|
||||||
|
// Artisan::call('mail:update-stats', ['--user' => $email]);
|
||||||
|
// $this->dispatch('$refresh');
|
||||||
|
// $this->dispatch('toast',
|
||||||
|
// type: 'done',
|
||||||
|
// badge: 'Mailbox',
|
||||||
|
// title: 'Mailbox aktualisiert',
|
||||||
|
// text: 'Die Mailbox-Statistiken wurden aktualisiert.',
|
||||||
|
// duration: 6000
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
// public function render()
|
// public function render()
|
||||||
// {
|
// {
|
||||||
// $system = Domain::query()->where('is_system', true)->first();
|
// $system = Domain::query()->where('is_system', true)->first();
|
||||||
|
|
@ -207,17 +274,17 @@ class MailboxList extends Component
|
||||||
// $domains = Domain::query()
|
// $domains = Domain::query()
|
||||||
// ->when($system, fn ($q) => $q->whereKeyNot($system->id))
|
// ->when($system, fn ($q) => $q->whereKeyNot($system->id))
|
||||||
//
|
//
|
||||||
// // Domain selbst ODER MailUser/ Aliasse müssen matchen
|
// // Domain selbst ODER MailUser müssen matchen
|
||||||
// ->when($hasTerm, function ($q) use ($needle) {
|
// ->when($hasTerm, function ($q) use ($needle) {
|
||||||
// $q->where(function ($w) use ($needle) {
|
// $q->where(function ($w) use ($needle) {
|
||||||
// $w->where('domain', 'like', $needle)
|
// $w->where('domain', 'like', $needle)
|
||||||
// ->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle));
|
// ->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle));
|
||||||
// });
|
// });
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// ->withCount(['mailUsers'])
|
// ->withCount(['mailUsers'])
|
||||||
//
|
//
|
||||||
// // Beziehungen zunächst gefiltert laden (damit "test" nur passende Mailboxen zeigt)
|
// // Relationen zunächst ggf. gefiltert laden
|
||||||
// ->with([
|
// ->with([
|
||||||
// 'mailUsers' => function ($q) use ($hasTerm, $needle) {
|
// 'mailUsers' => function ($q) use ($hasTerm, $needle) {
|
||||||
// if ($hasTerm) $q->where('localpart', 'like', $needle);
|
// if ($hasTerm) $q->where('localpart', 'like', $needle);
|
||||||
|
|
@ -228,35 +295,35 @@ class MailboxList extends Component
|
||||||
// ->orderBy('domain')
|
// ->orderBy('domain')
|
||||||
// ->get();
|
// ->get();
|
||||||
//
|
//
|
||||||
// // Domains, deren NAME den Suchbegriff trifft → ALLE Mailboxen/Aliasse zeigen
|
// // Wenn der Domainname selbst matched → alle Mailboxen/Aliasse vollständig nachladen
|
||||||
// if ($hasTerm) {
|
// if ($hasTerm) {
|
||||||
// $lower = Str::lower($term);
|
// $lower = Str::lower($term);
|
||||||
// foreach ($domains as $d) {
|
// foreach ($domains as $d) {
|
||||||
// if (Str::contains(Str::lower($d->domain), $lower)) {
|
// if (Str::contains(Str::lower($d->domain), $lower)) {
|
||||||
// // volle Relationen nachladen (überschreibt die gefilterten)
|
|
||||||
// $d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get());
|
// $d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get());
|
||||||
// $d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get());
|
// $d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get());
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // Vorbereitung für Blade (unverändert, arbeitet auf den ggf. gefilterten Relationen)
|
// // Vorbereitung für Blade
|
||||||
// foreach ($domains as $d) {
|
// foreach ($domains as $d) {
|
||||||
// $prepared = [];
|
// $prepared = [];
|
||||||
// $domainActive = (bool)($d->is_active ?? true);
|
// $domainActive = (bool)($d->is_active ?? true);
|
||||||
//
|
//
|
||||||
// foreach ($d->mailUsers as $u) {
|
// foreach ($d->mailUsers as $u) {
|
||||||
// $stats = Setting::get("mailbox.{$u->email}");
|
// $email = trim($u->email ?? '') !== ''
|
||||||
// $usedBytes = $stats['used_bytes'] ?? ($u->used_bytes ?? 0);
|
// ? $u->email
|
||||||
// $messageCount = $stats['message_count'] ?? ($u->message_count ?? 0);
|
// : ($u->localpart !== '' ? ($u->localpart.'@'.$d->domain) : null);
|
||||||
// $usedMB = (int) round(($usedBytes) / 1024 / 1024);
|
//
|
||||||
|
// $stats = $email ? Setting::get("mailbox.$email") : null;
|
||||||
|
//
|
||||||
|
// $usedBytes = is_array($stats) && isset($stats['used_bytes']) ? (int)$stats['used_bytes'] : (int)($u->used_bytes ?? 0);
|
||||||
|
// $messageCount = is_array($stats) && isset($stats['message_count']) ? (int)$stats['message_count'] : (int)($u->message_count ?? 0);
|
||||||
|
//
|
||||||
|
// $usedMB = (int) round($usedBytes / 1024 / 1024);
|
||||||
// $quota = (int)($u->quota_mb ?? 0);
|
// $quota = (int)($u->quota_mb ?? 0);
|
||||||
// $usage = $quota > 0 ? min(100, (int) round($usedMB / max(1,$quota) * 100)) : 0;
|
// $usage = $quota > 0 ? min(100, (int) round($usedMB / max(1, $quota) * 100)) : 0;
|
||||||
//
|
|
||||||
//
|
|
||||||
//// $quota = (int)($u->quota_mb ?? 0);
|
|
||||||
//// $used = (int)($u->used_mb ?? 0);
|
|
||||||
//// $usage = $quota > 0 ? min(100, (int)round($used / max(1, $quota) * 100)) : 0;
|
|
||||||
//
|
//
|
||||||
// $mailboxActive = (bool)($u->is_active ?? true);
|
// $mailboxActive = (bool)($u->is_active ?? true);
|
||||||
// $effective = $domainActive && $mailboxActive;
|
// $effective = $domainActive && $mailboxActive;
|
||||||
|
|
@ -272,7 +339,7 @@ class MailboxList extends Component
|
||||||
// 'localpart' => (string)$u->localpart,
|
// 'localpart' => (string)$u->localpart,
|
||||||
// 'quota_mb' => $quota,
|
// 'quota_mb' => $quota,
|
||||||
// 'usage_percent' => $usage,
|
// 'usage_percent' => $usage,
|
||||||
// 'used_mb' => $usedMB,
|
// 'used_mb' => $usedMB, // MiB fürs UI
|
||||||
// 'message_count' => $messageCount,
|
// 'message_count' => $messageCount,
|
||||||
// 'is_active' => $mailboxActive,
|
// 'is_active' => $mailboxActive,
|
||||||
// 'is_effective_active' => $effective,
|
// 'is_effective_active' => $effective,
|
||||||
|
|
@ -280,7 +347,6 @@ class MailboxList extends Component
|
||||||
// ];
|
// ];
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // für Blade
|
|
||||||
// $d->prepared_mailboxes = $prepared;
|
// $d->prepared_mailboxes = $prepared;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
@ -289,136 +355,228 @@ class MailboxList extends Component
|
||||||
// 'system' => $this->showSystemCard ? $system : null,
|
// 'system' => $this->showSystemCard ? $system : null,
|
||||||
// ]);
|
// ]);
|
||||||
// }
|
// }
|
||||||
|
//// public function render()
|
||||||
// public function render()
|
//// {
|
||||||
// {
|
//// $system = Domain::query()->where('is_system', true)->first();
|
||||||
// $system = Domain::query()->where('is_system', true)->first();
|
//// $term = trim($this->search);
|
||||||
// $term = trim($this->search);
|
//// $hasTerm = $term !== '';
|
||||||
|
//// $needle = '%'.str_replace(['%','_'], ['\%','\_'], $term).'%'; // LIKE-sicher
|
||||||
|
////
|
||||||
|
//// $domains = Domain::query()
|
||||||
|
//// ->when($system, fn ($q) => $q->whereKeyNot($system->id))
|
||||||
|
////
|
||||||
|
//// // Domain selbst ODER MailUser/ Aliasse müssen matchen
|
||||||
|
//// ->when($hasTerm, function ($q) use ($needle) {
|
||||||
|
//// $q->where(function ($w) use ($needle) {
|
||||||
|
//// $w->where('domain', 'like', $needle)
|
||||||
|
//// ->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle));
|
||||||
|
//// });
|
||||||
|
//// })
|
||||||
|
////
|
||||||
|
//// ->withCount(['mailUsers'])
|
||||||
|
////
|
||||||
|
//// // Beziehungen zunächst gefiltert laden (damit "test" nur passende Mailboxen zeigt)
|
||||||
|
//// ->with([
|
||||||
|
//// 'mailUsers' => function ($q) use ($hasTerm, $needle) {
|
||||||
|
//// if ($hasTerm) $q->where('localpart', 'like', $needle);
|
||||||
|
//// $q->orderBy('localpart');
|
||||||
|
//// },
|
||||||
|
//// ])
|
||||||
|
////
|
||||||
|
//// ->orderBy('domain')
|
||||||
|
//// ->get();
|
||||||
|
////
|
||||||
|
//// // Domains, deren NAME den Suchbegriff trifft → ALLE Mailboxen/Aliasse zeigen
|
||||||
|
//// if ($hasTerm) {
|
||||||
|
//// $lower = Str::lower($term);
|
||||||
|
//// foreach ($domains as $d) {
|
||||||
|
//// if (Str::contains(Str::lower($d->domain), $lower)) {
|
||||||
|
//// // volle Relationen nachladen (überschreibt die gefilterten)
|
||||||
|
//// $d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get());
|
||||||
|
//// $d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get());
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// // Vorbereitung für Blade (unverändert, arbeitet auf den ggf. gefilterten Relationen)
|
||||||
|
//// foreach ($domains as $d) {
|
||||||
|
//// $prepared = [];
|
||||||
|
//// $domainActive = (bool)($d->is_active ?? true);
|
||||||
|
////
|
||||||
|
//// foreach ($d->mailUsers as $u) {
|
||||||
|
//// $stats = Setting::get("mailbox.{$u->email}");
|
||||||
|
//// $usedBytes = $stats['used_bytes'] ?? ($u->used_bytes ?? 0);
|
||||||
|
//// $messageCount = $stats['message_count'] ?? ($u->message_count ?? 0);
|
||||||
|
//// $usedMB = (int) round(($usedBytes) / 1024 / 1024);
|
||||||
|
//// $quota = (int)($u->quota_mb ?? 0);
|
||||||
|
//// $usage = $quota > 0 ? min(100, (int) round($usedMB / max(1,$quota) * 100)) : 0;
|
||||||
|
////
|
||||||
|
////
|
||||||
|
////// $quota = (int)($u->quota_mb ?? 0);
|
||||||
|
////// $used = (int)($u->used_mb ?? 0);
|
||||||
|
////// $usage = $quota > 0 ? min(100, (int)round($used / max(1, $quota) * 100)) : 0;
|
||||||
|
////
|
||||||
|
//// $mailboxActive = (bool)($u->is_active ?? true);
|
||||||
|
//// $effective = $domainActive && $mailboxActive;
|
||||||
|
////
|
||||||
|
//// $reason = null;
|
||||||
|
//// if (!$effective) {
|
||||||
|
//// $reason = !$domainActive ? 'Domain inaktiv'
|
||||||
|
//// : (!$mailboxActive ? 'Postfach inaktiv' : null);
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// $prepared[] = [
|
||||||
|
//// 'id' => $u->id,
|
||||||
|
//// 'localpart' => (string)$u->localpart,
|
||||||
|
//// 'quota_mb' => $quota,
|
||||||
|
//// 'usage_percent' => $usage,
|
||||||
|
//// 'used_mb' => $usedMB,
|
||||||
|
//// 'message_count' => $messageCount,
|
||||||
|
//// 'is_active' => $mailboxActive,
|
||||||
|
//// 'is_effective_active' => $effective,
|
||||||
|
//// 'inactive_reason' => $reason,
|
||||||
|
//// ];
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// // für Blade
|
||||||
|
//// $d->prepared_mailboxes = $prepared;
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// return view('livewire.ui.mail.mailbox-list', [
|
||||||
|
//// 'domains' => $domains,
|
||||||
|
//// 'system' => $this->showSystemCard ? $system : null,
|
||||||
|
//// ]);
|
||||||
|
//// }
|
||||||
//
|
//
|
||||||
// $domains = Domain::query()
|
//// public function render()
|
||||||
// ->when($system, fn ($q) => $q->where('id', '!=', $system->id))
|
//// {
|
||||||
// ->withCount(['mailUsers','mailAliases'])
|
//// $system = Domain::query()->where('is_system', true)->first();
|
||||||
// ->with([
|
//// $term = trim($this->search);
|
||||||
// 'mailUsers' => fn ($q) => $q->orderBy('localpart'),
|
////
|
||||||
// 'mailAliases' => fn ($q) => $q->orderBy('local'),
|
//// $domains = Domain::query()
|
||||||
// ])
|
//// ->when($system, fn ($q) => $q->where('id', '!=', $system->id))
|
||||||
// ->when($term !== '', function ($q) use ($term) {
|
//// ->withCount(['mailUsers','mailAliases'])
|
||||||
// $q->where(function ($w) use ($term) {
|
//// ->with([
|
||||||
// $w->where('domain', 'like', "%{$term}%")
|
//// 'mailUsers' => fn ($q) => $q->orderBy('localpart'),
|
||||||
// ->orWhereHas('mailUsers', fn($u) =>
|
//// 'mailAliases' => fn ($q) => $q->orderBy('local'),
|
||||||
// $u->where('localpart', 'like', "%{$term}%")
|
//// ])
|
||||||
// );
|
//// ->when($term !== '', function ($q) use ($term) {
|
||||||
// });
|
//// $q->where(function ($w) use ($term) {
|
||||||
// })
|
//// $w->where('domain', 'like', "%{$term}%")
|
||||||
// ->orderBy('domain')
|
//// ->orWhereHas('mailUsers', fn($u) =>
|
||||||
// ->get();
|
//// $u->where('localpart', 'like', "%{$term}%")
|
||||||
|
//// );
|
||||||
|
//// });
|
||||||
|
//// })
|
||||||
|
//// ->orderBy('domain')
|
||||||
|
//// ->get();
|
||||||
|
////
|
||||||
|
//// // Vorbereitung für Blade (unverändert)
|
||||||
|
//// foreach ($domains as $d) {
|
||||||
|
//// $prepared = [];
|
||||||
|
//// $domainActive = (bool)($d->is_active ?? true);
|
||||||
|
////
|
||||||
|
//// foreach ($d->mailUsers as $u) {
|
||||||
|
//// $quota = (int) ($u->quota_mb ?? 0);
|
||||||
|
//// $used = (int) ($u->used_mb ?? 0);
|
||||||
|
//// $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0;
|
||||||
|
////
|
||||||
|
//// $mailboxActive = (bool)($u->is_active ?? true);
|
||||||
|
//// $effective = $domainActive && $mailboxActive;
|
||||||
|
////
|
||||||
|
//// $reason = null;
|
||||||
|
//// if (!$effective) {
|
||||||
|
//// $reason = !$domainActive ? 'Domain inaktiv'
|
||||||
|
//// : (!$mailboxActive ? 'Postfach inaktiv' : null);
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// $prepared[] = [
|
||||||
|
//// 'id' => $u->id,
|
||||||
|
//// 'localpart' => (string) $u->localpart,
|
||||||
|
//// 'quota_mb' => $quota,
|
||||||
|
//// 'used_mb' => $used,
|
||||||
|
//// 'usage_percent' => $usage,
|
||||||
|
//// 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0),
|
||||||
|
//// 'is_active' => $mailboxActive,
|
||||||
|
//// 'is_effective_active' => $effective,
|
||||||
|
//// 'inactive_reason' => $reason,
|
||||||
|
//// ];
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// $d->prepared_mailboxes = $prepared;
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// return view('livewire.ui.mail.mailbox-list', [
|
||||||
|
//// 'domains' => $domains,
|
||||||
|
//// 'system' => $this->showSystemCard ? $system : null,
|
||||||
|
//// ]);
|
||||||
|
//// }
|
||||||
//
|
//
|
||||||
// // Vorbereitung für Blade (unverändert)
|
//// public function render()
|
||||||
// foreach ($domains as $d) {
|
//// {
|
||||||
// $prepared = [];
|
//// $system = Domain::query()->where('is_system', true)->first();
|
||||||
// $domainActive = (bool)($d->is_active ?? true);
|
////
|
||||||
//
|
//// $term = trim($this->search);
|
||||||
// foreach ($d->mailUsers as $u) {
|
////
|
||||||
// $quota = (int) ($u->quota_mb ?? 0);
|
//// $domains = Domain::query()
|
||||||
// $used = (int) ($u->used_mb ?? 0);
|
//// ->when($system, fn ($q) => $q->where('id', '!=', $system->id))
|
||||||
// $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0;
|
//// ->withCount(['mailUsers','mailAliases'])
|
||||||
//
|
//// ->with([
|
||||||
// $mailboxActive = (bool)($u->is_active ?? true);
|
//// 'mailUsers' => fn ($q) => $q->orderBy('localpart'),
|
||||||
// $effective = $domainActive && $mailboxActive;
|
//// 'mailAliases' => fn ($q) => $q->orderBy('source'),
|
||||||
//
|
//// ])
|
||||||
// $reason = null;
|
//// ->when($term !== '', function ($q) use ($term) {
|
||||||
// if (!$effective) {
|
//// $q->where(function ($w) use ($term) {
|
||||||
// $reason = !$domainActive ? 'Domain inaktiv'
|
//// $w->where('domain', 'like', "%{$term}%")
|
||||||
// : (!$mailboxActive ? 'Postfach inaktiv' : null);
|
//// ->orWhereHas('mailUsers', fn($u) =>
|
||||||
// }
|
//// $u->where('localpart', 'like', "%{$term}%")
|
||||||
//
|
//// );
|
||||||
// $prepared[] = [
|
//// });
|
||||||
// 'id' => $u->id,
|
//// })
|
||||||
// 'localpart' => (string) $u->localpart,
|
//// ->orderBy('domain')
|
||||||
// 'quota_mb' => $quota,
|
//// ->get();
|
||||||
// 'used_mb' => $used,
|
////
|
||||||
// 'usage_percent' => $usage,
|
//// // Für das Blade vorbereiten (ohne Relations zu mutieren)
|
||||||
// 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0),
|
//// foreach ($domains as $d) {
|
||||||
// 'is_active' => $mailboxActive,
|
//// $prepared = [];
|
||||||
// 'is_effective_active' => $effective,
|
//// $domainActive = (bool)($d->is_active ?? true);
|
||||||
// 'inactive_reason' => $reason,
|
////
|
||||||
// ];
|
//// foreach ($d->mailUsers as $u) {
|
||||||
// }
|
//// $quota = (int) ($u->quota_mb ?? 0);
|
||||||
//
|
//// $used = (int) ($u->used_mb ?? 0);
|
||||||
// $d->prepared_mailboxes = $prepared;
|
//// $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0;
|
||||||
// }
|
////
|
||||||
//
|
//// $mailboxActive = (bool)($u->is_active ?? true);
|
||||||
// return view('livewire.ui.mail.mailbox-list', [
|
//// $effective = $domainActive && $mailboxActive;
|
||||||
// 'domains' => $domains,
|
////
|
||||||
// 'system' => $this->showSystemCard ? $system : null,
|
//// $reason = null;
|
||||||
// ]);
|
//// if (!$effective) {
|
||||||
// }
|
//// $reason = !$domainActive ? 'Domain inaktiv'
|
||||||
|
//// : (!$mailboxActive ? 'Postfach inaktiv' : null);
|
||||||
// public function render()
|
//// }
|
||||||
// {
|
////
|
||||||
// $system = Domain::query()->where('is_system', true)->first();
|
//// $prepared[] = [
|
||||||
//
|
//// 'id' => $u->id,
|
||||||
// $term = trim($this->search);
|
//// 'localpart' => (string) $u->localpart,
|
||||||
//
|
//// 'quota_mb' => $quota,
|
||||||
// $domains = Domain::query()
|
//// 'used_mb' => $used,
|
||||||
// ->when($system, fn ($q) => $q->where('id', '!=', $system->id))
|
//// 'usage_percent' => $usage,
|
||||||
// ->withCount(['mailUsers','mailAliases'])
|
//// 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0),
|
||||||
// ->with([
|
//// 'is_active' => $mailboxActive, // ursprünglicher Flag (falls du ihn brauchst)
|
||||||
// 'mailUsers' => fn ($q) => $q->orderBy('localpart'),
|
//// 'is_effective_active' => $effective, // ← NEU: Domain & Mailbox aktiv?
|
||||||
// 'mailAliases' => fn ($q) => $q->orderBy('source'),
|
//// 'inactive_reason' => $reason, // ← NEU: warum gesperrt
|
||||||
// ])
|
//// ];
|
||||||
// ->when($term !== '', function ($q) use ($term) {
|
//// }
|
||||||
// $q->where(function ($w) use ($term) {
|
////
|
||||||
// $w->where('domain', 'like', "%{$term}%")
|
//// $d->prepared_mailboxes = $prepared;
|
||||||
// ->orWhereHas('mailUsers', fn($u) =>
|
//// }
|
||||||
// $u->where('localpart', 'like', "%{$term}%")
|
////
|
||||||
// );
|
//// return view('livewire.ui.mail.mailbox-list', [
|
||||||
// });
|
//// 'domains' => $domains,
|
||||||
// })
|
//// 'system' => $this->showSystemCard ? $system : null,
|
||||||
// ->orderBy('domain')
|
//// ]);
|
||||||
// ->get();
|
//// }
|
||||||
//
|
//}
|
||||||
// // Für das Blade vorbereiten (ohne Relations zu mutieren)
|
|
||||||
// foreach ($domains as $d) {
|
|
||||||
// $prepared = [];
|
|
||||||
// $domainActive = (bool)($d->is_active ?? true);
|
|
||||||
//
|
|
||||||
// foreach ($d->mailUsers as $u) {
|
|
||||||
// $quota = (int) ($u->quota_mb ?? 0);
|
|
||||||
// $used = (int) ($u->used_mb ?? 0);
|
|
||||||
// $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0;
|
|
||||||
//
|
|
||||||
// $mailboxActive = (bool)($u->is_active ?? true);
|
|
||||||
// $effective = $domainActive && $mailboxActive;
|
|
||||||
//
|
|
||||||
// $reason = null;
|
|
||||||
// if (!$effective) {
|
|
||||||
// $reason = !$domainActive ? 'Domain inaktiv'
|
|
||||||
// : (!$mailboxActive ? 'Postfach inaktiv' : null);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $prepared[] = [
|
|
||||||
// 'id' => $u->id,
|
|
||||||
// 'localpart' => (string) $u->localpart,
|
|
||||||
// 'quota_mb' => $quota,
|
|
||||||
// 'used_mb' => $used,
|
|
||||||
// 'usage_percent' => $usage,
|
|
||||||
// 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0),
|
|
||||||
// 'is_active' => $mailboxActive, // ursprünglicher Flag (falls du ihn brauchst)
|
|
||||||
// 'is_effective_active' => $effective, // ← NEU: Domain & Mailbox aktiv?
|
|
||||||
// 'inactive_reason' => $reason, // ← NEU: warum gesperrt
|
|
||||||
// ];
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $d->prepared_mailboxes = $prepared;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return view('livewire.ui.mail.mailbox-list', [
|
|
||||||
// 'domains' => $domains,
|
|
||||||
// 'system' => $this->showSystemCard ? $system : null,
|
|
||||||
// ]);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue