Wire admin studio SSR and search infrastructure

This commit is contained in:
2026-05-01 11:46:06 +02:00
parent 257b0dbef6
commit 18cea8b0f0
329 changed files with 197465 additions and 2741 deletions

View File

@@ -12,6 +12,35 @@ use RuntimeException;
final class UploadDerivativesService
{
/**
* @var list<string>
*/
private const PASSTHROUGH_DOWNLOAD_EXTENSIONS = [
'jpg',
'jpeg',
'png',
'gif',
'webp',
'bmp',
'tif',
'tiff',
'svg',
'avif',
'heic',
'heif',
'ico',
'jfif',
'zip',
'rar',
'7z',
'7zip',
'tar',
'gz',
'tgz',
'bz2',
'xz',
];
private bool $imageAvailable = false;
private ?ImageManager $manager = null;
@@ -59,6 +88,49 @@ final class UploadDerivativesService
];
}
/**
* @return array{local_path: string, object_path: string, filename: string, mime: string, size: int, ext: string}
*/
public function storeDownloadOriginal(string $sourcePath, string $hash, ?string $originalFileName = null): array
{
$origExt = $this->resolveOriginalExtension($sourcePath, $originalFileName);
if (in_array($origExt, self::PASSTHROUGH_DOWNLOAD_EXTENSIONS, true)) {
return $this->storeOriginal($sourcePath, $hash, $originalFileName);
}
$filename = $hash . '.zip';
$target = $this->storage->localOriginalPath($hash, $filename);
File::delete($target);
$zip = new \ZipArchive();
$opened = $zip->open($target, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
if ($opened !== true) {
throw new RuntimeException('Unable to create zip archive for download original.');
}
try {
if (! $zip->addFile($sourcePath, $this->resolveDownloadArchiveEntryName($originalFileName, $hash, $origExt))) {
throw new RuntimeException('Unable to add source file to download archive.');
}
} finally {
$zip->close();
}
$size = (int) (filesize($target) ?: 0);
$objectPath = $this->storage->objectPathForVariant('original', $hash, $filename);
$this->storage->putObjectFromPath($target, $objectPath, 'application/zip');
return [
'local_path' => $target,
'object_path' => $objectPath,
'filename' => $filename,
'mime' => 'application/zip',
'size' => $size,
'ext' => 'zip',
];
}
private function resolveOriginalExtension(string $sourcePath, ?string $originalFileName): string
{
$fromClientName = strtolower((string) pathinfo((string) $originalFileName, PATHINFO_EXTENSION));
@@ -75,6 +147,20 @@ final class UploadDerivativesService
return $this->extensionFromMime($mime);
}
private function resolveDownloadArchiveEntryName(?string $originalFileName, string $hash, string $sourceExt): string
{
$candidate = trim((string) pathinfo((string) $originalFileName, PATHINFO_FILENAME));
$candidate = str_replace(['/', '\\'], '-', $candidate);
$candidate = trim((string) preg_replace('/[\x00-\x1F\x7F]/', '', $candidate));
$candidate = trim($candidate, ". \t\n\r\0\x0B");
if ($candidate === '' || $candidate === '.' || $candidate === '..') {
$candidate = $hash !== '' ? $hash : 'artwork';
}
return $candidate . '.' . ($sourceExt !== '' ? $sourceExt : 'bin');
}
private function extensionFromMime(string $mime): string
{
return match (strtolower($mime)) {