88 lines
2.8 KiB
PHP
88 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Services\Artworks\ArtworkPublicationService;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* PublishScheduledArtworksCommand
|
|
*
|
|
* Runs every minute (via Kernel schedule).
|
|
* Finds artworks with:
|
|
* - artwork_status = 'scheduled'
|
|
* - publish_at <= now() (UTC)
|
|
* - is_approved = true (respect moderation gate)
|
|
*
|
|
* Publishes each one:
|
|
* - sets is_public = true
|
|
* - sets published_at = now()
|
|
* - sets artwork_status = 'published'
|
|
* - dispatches Meilisearch reindex (via Scout)
|
|
* - records activity event
|
|
*
|
|
* Safe to run concurrently (DB row lock prevents double-publish).
|
|
*/
|
|
class PublishScheduledArtworksCommand extends Command
|
|
{
|
|
protected $signature = 'artworks:publish-scheduled
|
|
{--dry-run : List candidate artworks without publishing}
|
|
{--limit=100 : Max artworks to process per run}';
|
|
|
|
protected $description = 'Publish scheduled artworks whose publish_at datetime has passed.';
|
|
|
|
public function __construct(
|
|
private readonly ArtworkPublicationService $publicationService,
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function handle(): int
|
|
{
|
|
$dryRun = (bool) $this->option('dry-run');
|
|
$limit = (int) $this->option('limit');
|
|
|
|
$now = now()->utc();
|
|
|
|
$result = $this->publicationService->publishDueScheduled($limit, $now);
|
|
$candidates = $result['candidates'];
|
|
|
|
if ($candidates->isEmpty()) {
|
|
$this->line('No scheduled artworks due for publishing.');
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->info("Found {$candidates->count()} artwork(s) to publish." . ($dryRun ? ' [DRY RUN]' : ''));
|
|
|
|
$published = 0;
|
|
$errors = 0;
|
|
|
|
foreach ($candidates as $candidate) {
|
|
if ($dryRun) {
|
|
$this->line(" [dry-run] Would publish artwork #{$candidate->id}: \"{$candidate->title}\"");
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$artwork = $this->publicationService->publishIfDue($candidate, $now);
|
|
|
|
if ($artwork->artwork_status === 'published') {
|
|
$published++;
|
|
$this->line(" Published artwork #{$artwork->id}: \"{$artwork->title}\"");
|
|
}
|
|
} catch (\Throwable $e) {
|
|
$errors++;
|
|
Log::error("PublishScheduledArtworksCommand: failed to publish artwork #{$candidate->id}: {$e->getMessage()}");
|
|
$this->error(" Failed to publish #{$candidate->id}: {$e->getMessage()}");
|
|
}
|
|
}
|
|
|
|
if (! $dryRun) {
|
|
$this->info("Done. Published: {$published}, Errors: {$errors}.");
|
|
}
|
|
|
|
return $errors > 0 ? self::FAILURE : self::SUCCESS;
|
|
}
|
|
}
|