Featured artworks thumbnails
This commit is contained in:
99
app/Console/Commands/GenerateNewsCoverThumbnailsCommand.php
Normal file
99
app/Console/Commands/GenerateNewsCoverThumbnailsCommand.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Cdn\ArtworkCdnPurgeService;
|
||||
use App\Services\News\NewsCoverImageService;
|
||||
use App\Support\News\NewsCoverImage;
|
||||
use Illuminate\Console\Command;
|
||||
use cPad\Plugins\News\Models\NewsArticle;
|
||||
|
||||
final class GenerateNewsCoverThumbnailsCommand extends Command
|
||||
{
|
||||
protected $signature = 'news:generate-cover-thumbnails {--id=* : Restrict to one or more news article IDs} {--force : Regenerate variants even when they already exist}';
|
||||
|
||||
protected $description = 'Generate missing responsive cover thumbnails for managed news cover images';
|
||||
|
||||
public function __construct(
|
||||
private readonly NewsCoverImageService $covers,
|
||||
private readonly ArtworkCdnPurgeService $cdnPurge,
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$ids = collect((array) $this->option('id'))
|
||||
->map(static fn (mixed $id): int => (int) $id)
|
||||
->filter(static fn (int $id): bool => $id > 0)
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$force = (bool) $this->option('force');
|
||||
|
||||
$query = NewsArticle::query()
|
||||
->select(['id', 'title', 'cover_image'])
|
||||
->whereNotNull('cover_image')
|
||||
->where('cover_image', '!=', '');
|
||||
|
||||
if ($ids !== []) {
|
||||
$query->whereIn('id', $ids);
|
||||
}
|
||||
|
||||
$generated = 0;
|
||||
$skipped = 0;
|
||||
$failed = 0;
|
||||
$purged = 0;
|
||||
|
||||
$query->orderBy('id')->chunkById(100, function ($articles) use (&$generated, &$skipped, &$failed, &$purged, $force): void {
|
||||
foreach ($articles as $article) {
|
||||
$path = trim((string) $article->cover_image);
|
||||
|
||||
if (! NewsCoverImage::isManagedPath($path)) {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->covers->ensureVariants($path, $force);
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
$this->warn(sprintf('Article %d failed: %s', (int) $article->id, $e->getMessage()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($result['generated'] ?? 0) > 0) {
|
||||
$generated++;
|
||||
|
||||
if ($force && $this->purgeVariantCache($path, (int) $article->id)) {
|
||||
$purged++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$skipped++;
|
||||
}
|
||||
});
|
||||
|
||||
$this->info(sprintf('News cover thumbnail generation complete: generated=%d skipped=%d failed=%d purged=%d', $generated, $skipped, $failed, $purged));
|
||||
|
||||
return $failed > 0 ? self::FAILURE : self::SUCCESS;
|
||||
}
|
||||
|
||||
private function purgeVariantCache(string $path, int $articleId): bool
|
||||
{
|
||||
$variantPaths = array_values(array_map(
|
||||
static fn (string $variant): string => NewsCoverImage::variantPath($path, $variant),
|
||||
array_keys(NewsCoverImage::VARIANTS),
|
||||
));
|
||||
|
||||
return $this->cdnPurge->purgeArtworkObjectPaths($variantPaths, [
|
||||
'article_id' => $articleId,
|
||||
'reason' => 'news_cover_thumbnails_regenerated',
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user