feat(cms): sync site assets, revalidate webhook, and document download naming

This commit is contained in:
2026-02-10 23:38:31 +08:00
parent c4969cd4d2
commit b6e18a83ec
27 changed files with 1019 additions and 26 deletions

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Support;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class DownloadFile
{
/**
* Create a download response with UTF-8 filename support.
*/
public static function fromDisk(
string $disk,
string $path,
string $downloadName,
array $headers = []
): Response {
$safeName = static::asciiFallbackFilename($downloadName);
$response = Storage::disk($disk)->download($path, $safeName, $headers);
$response->headers->set('Content-Disposition', static::contentDisposition($downloadName));
return $response;
}
/**
* Build RFC 5987 compatible Content-Disposition value.
*/
public static function contentDisposition(
string $downloadName,
string $type = 'attachment'
): string {
$safeOriginalName = static::sanitizeHeaderFilename($downloadName);
$safeFallback = addcslashes(static::asciiFallbackFilename($safeOriginalName), "\"\\");
$encoded = rawurlencode($safeOriginalName);
return "{$type}; filename=\"{$safeFallback}\"; filename*=UTF-8''{$encoded}";
}
/**
* Generate ASCII fallback filename for old clients.
*/
public static function asciiFallbackFilename(string $filename): string
{
$filename = static::sanitizeHeaderFilename($filename);
$extension = pathinfo($filename, PATHINFO_EXTENSION);
$basename = pathinfo($filename, PATHINFO_FILENAME);
$asciiBase = Str::ascii($basename);
$asciiBase = preg_replace('/[^A-Za-z0-9._-]+/', '_', (string) $asciiBase);
$asciiBase = trim((string) $asciiBase, '._-');
if ($asciiBase === '') {
$asciiBase = 'download';
}
$asciiExtension = Str::ascii((string) $extension);
$asciiExtension = preg_replace('/[^A-Za-z0-9]+/', '', (string) $asciiExtension);
return $asciiExtension === ''
? $asciiBase
: "{$asciiBase}.{$asciiExtension}";
}
private static function sanitizeHeaderFilename(string $filename): string
{
$filename = str_replace(["\r", "\n"], '', trim($filename));
return $filename !== '' ? $filename : 'download';
}
}