*/ public function milestones(): array { return array_values(array_map( 'intval', (array) config('notifications.hosting_expiry_milestones', [30, 14, 7, 3, 1]) )); } public function checkAll(): int { $sent = 0; HostingAccount::query() ->where('status', HostingAccount::STATUS_ACTIVE) ->whereNotNull('expires_at') ->where('expires_at', '>', now()) ->with('user') ->each(function (HostingAccount $account) use (&$sent): void { if ($this->checkAccount($account)) { $sent++; } }); return $sent; } public function checkAccount(HostingAccount $account): bool { if (! $account->expires_at || ! $account->user || $account->expires_at->isPast()) { return false; } $daysRemaining = $this->daysUntilExpiry($account); if (! in_array($daysRemaining, $this->milestones(), true)) { return false; } $metadata = is_array($account->metadata) ? $account->metadata : []; $sent = array_map('intval', (array) ($metadata['expiry_alerts_sent'] ?? [])); if (in_array($daysRemaining, $sent, true)) { return false; } $account->user->notify(new HostingExpiringNotification($account, $daysRemaining)); $metadata['expiry_alerts_sent'] = array_values(array_unique([...$sent, $daysRemaining])); $account->update(['metadata' => $metadata]); return true; } public function resetAlerts(HostingAccount $account): void { $metadata = is_array($account->metadata) ? $account->metadata : []; unset($metadata['expiry_alerts_sent']); $account->update(['metadata' => $metadata]); } private function daysUntilExpiry(HostingAccount $account): int { return (int) now()->startOfDay()->diffInDays( $account->expires_at->copy()->startOfDay(), false ); } }