Init(Core): Change repo

This commit is contained in:
2026-04-24 15:29:37 +03:30
commit ededb41a3a
1499 changed files with 199187 additions and 0 deletions

View 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;
}
}