Init(Core): Change repo
This commit is contained in:
135
app/Console/Commands/AddSubscriptionDays.php
Normal file
135
app/Console/Commands/AddSubscriptionDays.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\SubscribePlan;
|
||||
use App\Models\User;
|
||||
use App\Models\UserSubscriber;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class AddSubscriptionDays extends Command
|
||||
{
|
||||
protected $signature = 'subscriptions:add-days
|
||||
{days=3 : Number of days to add}
|
||||
{--all-users : Ensure every user gets days even if they have no subscription}
|
||||
{--only-without-subscription : Process only users who do not have any subscription}
|
||||
{--plan-id= : Subscribe plan id to use for users without a subscription}
|
||||
{--include-expired : Also extend expired subscriptions}
|
||||
{--chunk=1000 : Chunk size for processing}
|
||||
{--dry-run : Show how many records would change without saving}';
|
||||
|
||||
protected $description = 'Add days to all user subscriptions';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$days = (int) $this->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;
|
||||
}
|
||||
}
|
||||
27
app/Console/Kernel.php
Normal file
27
app/Console/Kernel.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user