argument('days'); $chunkSize = max(1, (int) $this->option('chunk')); $includeExpired = (bool) $this->option('include-expired'); $allUsers = (bool) $this->option('all-users'); $onlyWithoutSubscription = (bool) $this->option('only-without-subscription'); $dryRun = (bool) $this->option('dry-run'); if ($days <= 0) { $this->error('Days must be a positive integer.'); return self::FAILURE; } if ($onlyWithoutSubscription && !$allUsers) { $this->error('The --only-without-subscription option can only be used with --all-users.'); return self::FAILURE; } if ($allUsers) { $planId = $this->option('plan-id'); if (!$planId) { $this->error('When using --all-users you must provide --plan-id for users without a subscription.'); return self::FAILURE; } $plan = SubscribePlan::find($planId); if (!$plan) { $this->error('Subscribe plan not found for the given --plan-id.'); return self::FAILURE; } } if ($allUsers) { if ($onlyWithoutSubscription) { $this->info("Granting {$days} day(s) only to users without a subscription." . ($dryRun ? ' (dry-run)' : '')); } else { $this->info("Granting {$days} day(s) to every user." . ($dryRun ? ' (dry-run)' : '')); } } else { $scopeLabel = $includeExpired ? 'all' : 'active'; $this->info("Extending {$scopeLabel} subscriptions by {$days} day(s)." . ($dryRun ? ' (dry-run)' : '')); } $touched = 0; if ($allUsers) { $planId = (int) $this->option('plan-id'); $isFree = (bool) $plan->is_free; User::query()->orderBy('id')->chunkById($chunkSize, function ($users) use (&$touched, $days, $dryRun, $planId, $isFree, $onlyWithoutSubscription) { foreach ($users as $user) { $latest = $user->userSubscribers()->orderByDesc('expired_at')->first(); if ($onlyWithoutSubscription && $latest) { continue; } $touched++; if ($dryRun) { continue; } if ($latest) { $baseDate = $latest->expired_at && $latest->expired_at->greaterThan(now()) ? $latest->expired_at : now(); $latest->expired_at = $baseDate->copy()->addDays($days); $latest->save(); } else { $user->userSubscribers()->create([ 'subscribe_plan_id' => $planId, 'expired_at' => now()->addDays($days), 'is_free' => $isFree, ]); } } }); } else { $query = UserSubscriber::query(); if (!$includeExpired) { $query->where('expired_at', '>', now()); } $query->orderBy('id')->chunkById($chunkSize, function ($subscribers) use (&$touched, $days, $dryRun) { foreach ($subscribers as $subscriber) { $touched++; if ($dryRun) { continue; } if ($subscriber->expired_at === null) { $subscriber->expired_at = now()->addDays($days); } else { $subscriber->expired_at = $subscriber->expired_at->copy()->addDays($days); } $subscriber->save(); } }); } if ($dryRun) { $label = $allUsers ? 'user(s)' : 'subscription record(s)'; $this->info("{$touched} {$label} would be processed."); } else { $label = $allUsers ? 'user(s)' : 'subscription record(s)'; $this->info("{$touched} {$label} processed."); } return self::SUCCESS; } }