115 lines
3.4 KiB
PHP
115 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Jobs\PullPackageFromPaddle;
|
|
use App\Jobs\SyncPackageToPaddle;
|
|
use App\Models\Package;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Str;
|
|
|
|
class PaddleSyncPackages extends Command
|
|
{
|
|
protected $signature = 'paddle:sync-packages
|
|
{--package=* : Limit sync to the given package IDs or slugs}
|
|
{--dry-run : Generate payload snapshots without calling Paddle}
|
|
{--pull : Fetch remote Paddle state instead of pushing local changes}
|
|
{--queue : Dispatch jobs onto the queue instead of running synchronously}';
|
|
|
|
protected $description = 'Synchronise local packages with Paddle products and prices.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$packages = $this->resolvePackages();
|
|
|
|
if ($packages->isEmpty()) {
|
|
$this->warn('No packages matched the given filters.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$dryRun = (bool) $this->option('dry-run');
|
|
$pull = (bool) $this->option('pull');
|
|
$queue = (bool) $this->option('queue');
|
|
|
|
$packages->each(function (Package $package) use ($dryRun, $pull, $queue) {
|
|
if ($pull) {
|
|
$this->dispatchPullJob($package, $queue);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->dispatchSyncJob($package, $dryRun, $queue);
|
|
});
|
|
|
|
$this->info(sprintf(
|
|
'Queued %d package %s for Paddle %s.',
|
|
$packages->count(),
|
|
Str::plural('entry', $packages->count()),
|
|
$pull ? 'pull' : 'sync'
|
|
));
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
protected function resolvePackages(): Collection
|
|
{
|
|
$keys = collect((array) $this->option('package'))->filter();
|
|
|
|
$query = Package::query();
|
|
|
|
if ($keys->isNotEmpty()) {
|
|
$ids = $keys
|
|
->filter(fn ($value) => is_numeric($value))
|
|
->map(fn ($value) => (int) $value);
|
|
|
|
$slugs = $keys
|
|
->reject(fn ($value) => is_numeric($value))
|
|
->values();
|
|
|
|
$query->where(function ($builder) use ($ids, $slugs) {
|
|
if ($ids->isNotEmpty()) {
|
|
$builder->orWhereIn('id', $ids);
|
|
}
|
|
|
|
if ($slugs->isNotEmpty()) {
|
|
$builder->orWhereIn('slug', $slugs);
|
|
}
|
|
});
|
|
}
|
|
|
|
return $query->orderByDesc('id')->get();
|
|
}
|
|
|
|
protected function dispatchSyncJob(Package $package, bool $dryRun, bool $queue): void
|
|
{
|
|
$context = [
|
|
'dry_run' => $dryRun,
|
|
];
|
|
|
|
if ($queue) {
|
|
SyncPackageToPaddle::dispatch($package->id, $context);
|
|
$this->line(sprintf('> queued sync for package #%d (%s)', $package->id, $package->slug));
|
|
|
|
return;
|
|
}
|
|
|
|
SyncPackageToPaddle::dispatchSync($package->id, $context);
|
|
$this->line(sprintf('> synced package #%d (%s)', $package->id, $package->slug));
|
|
}
|
|
|
|
protected function dispatchPullJob(Package $package, bool $queue): void
|
|
{
|
|
if ($queue) {
|
|
PullPackageFromPaddle::dispatch($package->id);
|
|
$this->line(sprintf('> queued pull for package #%d (%s)', $package->id, $package->slug));
|
|
|
|
return;
|
|
}
|
|
|
|
PullPackageFromPaddle::dispatchSync($package->id);
|
|
$this->line(sprintf('> pulled package #%d (%s)', $package->id, $package->slug));
|
|
}
|
|
}
|