Current state with latest updates
This commit is contained in:
@@ -7,8 +7,10 @@ namespace App\Services\Images;
|
||||
use App\Models\Artwork;
|
||||
use App\Services\Cdn\ArtworkCdnPurgeService;
|
||||
use App\Services\ArtworkOriginalFileLocator;
|
||||
use App\Services\HomepageService;
|
||||
use App\Services\Uploads\UploadStorageService;
|
||||
use App\Support\ArtworkFeaturedImagePath;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\Drivers\Gd\Driver as GdDriver;
|
||||
@@ -28,6 +30,7 @@ final class FeaturedArtworkThumbnailGenerator
|
||||
private readonly ArtworkOriginalFileLocator $locator,
|
||||
private readonly UploadStorageService $storage,
|
||||
private readonly ArtworkCdnPurgeService $cdnPurge,
|
||||
private readonly HomepageService $homepage,
|
||||
) {
|
||||
try {
|
||||
$this->manager = extension_loaded('gd')
|
||||
@@ -59,6 +62,8 @@ final class FeaturedArtworkThumbnailGenerator
|
||||
$missing[] = $variant;
|
||||
}
|
||||
|
||||
$this->persistVariantState($artwork, $existing);
|
||||
|
||||
return [
|
||||
'existing' => $existing,
|
||||
'missing' => $missing,
|
||||
@@ -66,6 +71,52 @@ final class FeaturedArtworkThumbnailGenerator
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Record which featured variants are known to exist so the public homepage can read
|
||||
* this state instead of checking the remote disk during a request.
|
||||
*
|
||||
* saveQuietly() intentionally bypasses model observers (ArtworkObserver /
|
||||
* ArtworkFeatureObserver never fire for this write), so cache invalidation for the
|
||||
* homepage hero cannot be delegated to them here — it has to happen inline, and only
|
||||
* when the persisted availability actually changed for an artwork that is currently
|
||||
* an active feature (otherwise routine --all/--missing-only audits over thousands of
|
||||
* non-featured artworks would repeatedly invalidate the guest payload cache for no
|
||||
* reason and cause a stampede).
|
||||
*
|
||||
* @param list<string> $existingVariants
|
||||
*/
|
||||
private function persistVariantState(Artwork $artwork, array $existingVariants): void
|
||||
{
|
||||
$existingVariants = array_values(array_unique($existingVariants));
|
||||
sort($existingVariants);
|
||||
|
||||
$previousVariants = (array) ($artwork->featured_thumbnail_variants_json ?? []);
|
||||
sort($previousVariants);
|
||||
|
||||
$changed = $previousVariants !== $existingVariants;
|
||||
|
||||
$artwork->forceFill([
|
||||
'featured_thumbnail_variants_json' => $existingVariants,
|
||||
'featured_thumbnails_checked_at' => now(),
|
||||
])->saveQuietly();
|
||||
|
||||
if ($changed && $this->isActivelyFeatured($artwork)) {
|
||||
$this->homepage->clearFeaturedAndMedalCaches();
|
||||
}
|
||||
}
|
||||
|
||||
private function isActivelyFeatured(Artwork $artwork): bool
|
||||
{
|
||||
return DB::table('artwork_features')
|
||||
->where('artwork_id', $artwork->id)
|
||||
->where('is_active', true)
|
||||
->whereNull('deleted_at')
|
||||
->where(function ($query): void {
|
||||
$query->whereNull('expires_at')->orWhere('expires_at', '>', now());
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{existing:list<string>,missing:list<string>,target_variants:list<string>,generated:int,skipped:int,generated_variants:list<string>,generated_paths:list<string>,failed:array<string,string>}
|
||||
*/
|
||||
@@ -129,6 +180,10 @@ final class FeaturedArtworkThumbnailGenerator
|
||||
]);
|
||||
}
|
||||
|
||||
if ($generatedVariants !== []) {
|
||||
$this->persistVariantState($artwork, array_values(array_unique([...$plan['existing'], ...$generatedVariants])));
|
||||
}
|
||||
|
||||
return $plan + [
|
||||
'generated' => count($generatedVariants),
|
||||
'skipped' => max(0, count($targetVariants) - count($generatedVariants) - count($failed)) + count($plan['existing']),
|
||||
|
||||
Reference in New Issue
Block a user