make:command RestockProducts writes an auto-registered class in app/Console/Commands; Laravel 13 2,157 's stub uses #[Signature] and #[Description] attributes instead of $signature:
#[Signature('shop:restock {sku?* : Only these SKUs} {--t|threshold=5 : Restock below this}
{--amount=20 : Copies to add to each title} {--dry-run : List the titles only}')]
#[Description('Top up stock for titles that are running low')]
class RestockProducts extends Command
{
public function handle(): int
{
$low = Product::where('stock', '<', (int) $this->option('threshold'))
->when($this->argument('sku'), fn ($q, $skus) => $q->whereIn('sku', $skus))
->orderBy('sku')->get();
$this->table(['SKU', 'Title', 'Stock'], $low->map->only('sku', 'title', 'stock'));
if ($low->isEmpty() || $this->option('dry-run')) {
return self::SUCCESS;
}
$amount = (int) $this->option('amount');
$chosen = $this->chooseTitles($low, $amount);
$this->withProgressBar($chosen, function (Product $p) use ($amount) {
$p->increment('stock', $amount);
ProductRestocked::dispatch($p, $amount);
});
$this->newLine();
$this->info("Added {$amount} copies to each title.");
return self::SUCCESS;
}Output
$ php artisan shop:restock BK-103 --no-interaction +--------+--------------------+-------+ | SKU | Title | Stock | +--------+--------------------+-------+ | BK-103 | Apache in Practice | 0 | +--------+--------------------+-------+ 0/1 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0% 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% Added 20 copies to each title.
{sku?*} is an optional array argument, {--t|threshold=5} an option with shortcut and default, {--dry-run} a switch; text after a colon feeds help shop:restock. handle() may type-hint services, and returns the exit code. Of the 127 commands here, 37 are make:*; the daily ones are about, route:list, migrate:status, db:show, tinker, queue:work, schedule:list, optimize:clear, down and up.