where('is_active', true); if ($email = $this->option('user')) { $query->where('email', $email); } $users = $query->get(); foreach ($users as $u) { $email = $u->email; [$messages, $vsize] = $this->fetchViaDoveadm($email); if ($messages === null || $vsize === null) { if (config('mailpool.fallback_du')) { [$messages, $vsize] = $this->fallbackDu($email); } } $u->update([ 'message_count' => (int)($messages ?? 0), 'used_bytes' => (int)($vsize ?? 0), 'stats_refreshed_at' => now(), ]); $this->line(sprintf( '%-35s %6.1f MiB %5d msgs', $email, ($vsize ?? 0) / 1024 / 1024, $messages ?? 0 )); } $this->info('Mailbox-Statistiken aktualisiert.'); return Command::SUCCESS; } /** @return array{0:int|null,1:int|null} [messages, vsize] */ private function fetchViaDoveadm(string $email): array { $bin = config('mailpool.doveadm'); $sudo = config('mailpool.doveadm_sudo'); $cmd = [$bin, 'mailbox', 'status', '-u', $email, 'messages', 'vsize', 'INBOX']; if ($sudo) array_unshift($cmd, 'sudo', '-n'); $p = new Process($cmd); $p->setTimeout(10); $p->run(); if (!$p->isSuccessful()) { return [null, null]; } $out = trim($p->getOutput()); $messages = preg_match('/\bmessages=(\d+)/', $out, $m) ? (int)$m[1] : null; $vsize = preg_match('/\bvsize=(\d+)/', $out, $m) ? (int)$m[1] : null; return [$messages, $vsize]; } /** Fallback mit du (nur Größe, keine Message-Zählung) */ private function fallbackDu(string $email): array { [$local, $domain] = explode('@', $email, 2); $path = rtrim(config('mailpool.mailroot'), '/') . "/{$domain}/{$local}"; $p = new Process(['bash', '-lc', 'du -sb ' . escapeshellarg($path) . ' 2>/dev/null | cut -f1']); $p->setTimeout(10)->run(); $bytes = $p->isSuccessful() ? (int)trim($p->getOutput()) : 0; return [null, $bytes]; } } // //namespace App\Console\Commands; // //use App\Models\MailUser; //use Illuminate\Console\Command; // //class UpdateMailboxStats extends Command //{ // protected $signature = 'mail:update-stats {--user=}'; // protected $description = 'Aktualisiert Mailquota und Nachrichtenzahl für alle Mailboxen (oder einen spezifischen Benutzer)'; // // public function handle(): int // { // $query = MailUser::query()->where('is_active', true); // // if ($email = $this->option('user')) { // $query->where('email', $email); // } // // $users = $query->get(); // // foreach ($users as $u) { // $email = $u->email; // $domain = explode('@', $email)[1]; // $local = explode('@', $email)[0]; // $path = "/var/mail/vhosts/{$domain}/{$local}"; // // $usedBytes = 0; // $messageCount = 0; // // if (is_dir($path)) { // $usedBytes = (int) trim(shell_exec('du -sb '.escapeshellarg($path).' 2>/dev/null | cut -f1')); // } // // $out = trim(shell_exec('doveadm mailbox status -u '.escapeshellarg($email).' messages INBOX 2>/dev/null')); // if (preg_match('/messages=(\d+)/', $out, $m)) { // $messageCount = (int) $m[1]; // } // // $u->update([ // 'used_bytes' => $usedBytes, // 'message_count' => $messageCount, // 'stats_refreshed_at' => now(), // ]); // // $this->info(sprintf("%-35s %6.1f MiB %4d Nachrichten", $email, $usedBytes / 1024 / 1024, $messageCount)); // } // // return Command::SUCCESS; // } //}