Implement creator studio and upload updates
This commit is contained in:
145
app/Services/Cdn/ArtworkCdnPurgeService.php
Normal file
145
app/Services/Cdn/ArtworkCdnPurgeService.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Cdn;
|
||||
|
||||
use App\Services\ThumbnailService;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
final class ArtworkCdnPurgeService
|
||||
{
|
||||
/**
|
||||
* @param array<int, string> $objectPaths
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
public function purgeArtworkObjectPaths(array $objectPaths, array $context = []): bool
|
||||
{
|
||||
$urls = array_values(array_unique(array_filter(array_map(
|
||||
fn (mixed $path): ?string => is_string($path) && trim($path) !== ''
|
||||
? $this->cdnUrlForObjectPath($path)
|
||||
: null,
|
||||
$objectPaths,
|
||||
))));
|
||||
|
||||
return $this->purgeUrls($urls, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $variants
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
public function purgeArtworkHashVariants(string $hash, string $extension = 'webp', array $variants = ['xs', 'sm', 'md', 'lg', 'xl', 'sq'], array $context = []): bool
|
||||
{
|
||||
$urls = array_values(array_unique(array_filter(array_map(
|
||||
fn (string $variant): ?string => ThumbnailService::fromHash($hash, $extension, $variant),
|
||||
$variants,
|
||||
))));
|
||||
|
||||
return $this->purgeUrls($urls, $context + ['hash' => $hash]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $urls
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
private function purgeUrls(array $urls, array $context = []): bool
|
||||
{
|
||||
if ($urls === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->hasCloudflareCredentials()) {
|
||||
return $this->purgeViaCloudflare($urls, $context);
|
||||
}
|
||||
|
||||
$legacyPurgeUrl = trim((string) config('cdn.purge_url', ''));
|
||||
if ($legacyPurgeUrl !== '') {
|
||||
return $this->purgeViaLegacyWebhook($legacyPurgeUrl, $urls, $context);
|
||||
}
|
||||
|
||||
Log::debug('CDN purge skipped - no Cloudflare or legacy purge configuration is available', $context + [
|
||||
'url_count' => count($urls),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function purgeViaCloudflare(array $urls, array $context): bool
|
||||
{
|
||||
$purgeUrl = sprintf(
|
||||
'https://api.cloudflare.com/client/v4/zones/%s/purge_cache',
|
||||
trim((string) config('cdn.cloudflare.zone_id')),
|
||||
);
|
||||
|
||||
try {
|
||||
$response = Http::timeout(10)
|
||||
->acceptJson()
|
||||
->withToken(trim((string) config('cdn.cloudflare.api_token')))
|
||||
->post($purgeUrl, ['files' => $urls]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::warning('Cloudflare artwork CDN purge failed', $context + [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
'url_count' => count($urls),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Cloudflare artwork CDN purge threw an exception', $context + [
|
||||
'error' => $e->getMessage(),
|
||||
'url_count' => count($urls),
|
||||
]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function purgeViaLegacyWebhook(string $purgeUrl, array $urls, array $context): bool
|
||||
{
|
||||
$paths = array_values(array_unique(array_filter(array_map(function (string $url): ?string {
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
|
||||
return is_string($path) && $path !== '' ? $path : null;
|
||||
}, $urls))));
|
||||
|
||||
if ($paths === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::timeout(10)->acceptJson()->post($purgeUrl, ['paths' => $paths]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::warning('Legacy artwork CDN purge failed', $context + [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
'path_count' => count($paths),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Legacy artwork CDN purge threw an exception', $context + [
|
||||
'error' => $e->getMessage(),
|
||||
'path_count' => count($paths),
|
||||
]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasCloudflareCredentials(): bool
|
||||
{
|
||||
return trim((string) config('cdn.cloudflare.zone_id', '')) !== ''
|
||||
&& trim((string) config('cdn.cloudflare.api_token', '')) !== '';
|
||||
}
|
||||
|
||||
private function cdnUrlForObjectPath(string $objectPath): string
|
||||
{
|
||||
return rtrim((string) config('cdn.files_url', 'https://cdn.skinbase.org'), '/') . '/' . ltrim($objectPath, '/');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user