61 lines
1.8 KiB
PHP
61 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Shared\Storage\Services;
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use InvalidArgumentException;
|
|
|
|
class TemporaryUrlService
|
|
{
|
|
protected const REFRESH_MARGIN_SECONDS = 60;
|
|
|
|
/**
|
|
* @return array{temporary_url: string, temporary_url_expires_at: string}
|
|
*/
|
|
public function generate(string $path, int $expiresInMinutes = 10): array
|
|
{
|
|
if ($expiresInMinutes < 1) {
|
|
throw new InvalidArgumentException('The temporary URL expiration must be at least one minute.');
|
|
}
|
|
|
|
$cacheTtlInSeconds = max(
|
|
1,
|
|
($expiresInMinutes * 60) - self::REFRESH_MARGIN_SECONDS,
|
|
);
|
|
|
|
return Cache::remember(
|
|
$this->cacheKey($path, $expiresInMinutes),
|
|
now()->addSeconds($cacheTtlInSeconds),
|
|
function () use ($path, $expiresInMinutes): array {
|
|
$expiresAt = now()->addMinutes($expiresInMinutes);
|
|
|
|
return [
|
|
'temporary_url' => Storage::disk('s3')->temporaryUrl(
|
|
$path,
|
|
$expiresAt,
|
|
[
|
|
'ResponseCacheControl' => 'private, max-age='.($expiresInMinutes * 60),
|
|
],
|
|
),
|
|
'temporary_url_expires_at' => $expiresAt->toIso8601String(),
|
|
];
|
|
},
|
|
);
|
|
}
|
|
|
|
public function forget(string $path, int $expiresInMinutes = 10): void
|
|
{
|
|
Cache::forget($this->cacheKey($path, $expiresInMinutes));
|
|
}
|
|
|
|
protected function cacheKey(string $path, int $expiresInMinutes): string
|
|
{
|
|
return sprintf(
|
|
's3:temporary-url:%s:%d',
|
|
hash('sha256', $path),
|
|
$expiresInMinutes,
|
|
);
|
|
}
|
|
}
|