*/ public function milestones(): array { return array_values(array_map( 'intval', (array) config('notifications.pro_expiry_milestones', [7, 3, 1]) )); } public function checkAll(): int { $sent = 0; ProSubscription::query() ->whereIn('status', [ProSubscription::STATUS_ACTIVE, ProSubscription::STATUS_CANCELED]) ->whereNotNull('current_period_end') ->where('current_period_end', '>', now()) ->with('user') ->each(function (ProSubscription $subscription) use (&$sent): void { if ($this->checkSubscription($subscription)) { $sent++; } }); return $sent; } public function checkSubscription(ProSubscription $subscription): bool { if (! $subscription->current_period_end || ! $subscription->user || $subscription->current_period_end->isPast()) { return false; } if ($subscription->auto_renew && $subscription->status === ProSubscription::STATUS_ACTIVE) { return false; } $daysRemaining = $this->daysUntilExpiry($subscription); if (! in_array($daysRemaining, $this->milestones(), true)) { return false; } $metadata = is_array($subscription->metadata) ? $subscription->metadata : []; $sent = array_map('intval', (array) ($metadata['expiry_alerts_sent'] ?? [])); if (in_array($daysRemaining, $sent, true)) { return false; } $this->notifications->proExpiring($subscription, $daysRemaining); $metadata['expiry_alerts_sent'] = array_values(array_unique([...$sent, $daysRemaining])); $subscription->update(['metadata' => $metadata]); return true; } public function resetAlerts(ProSubscription $subscription): void { $metadata = is_array($subscription->metadata) ? $subscription->metadata : []; unset($metadata['expiry_alerts_sent']); $subscription->update(['metadata' => $metadata]); } private function daysUntilExpiry(ProSubscription $subscription): int { return (int) now()->startOfDay()->diffInDays( $subscription->current_period_end->copy()->startOfDay(), false ); } }