feat: ship creator journey v2 and profile updates
This commit is contained in:
98
app/Services/ContentTypeAssetService.php
Normal file
98
app/Services/ContentTypeAssetService.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ContentType;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use RuntimeException;
|
||||
|
||||
final class ContentTypeAssetService
|
||||
{
|
||||
private const ALLOWED_MIME_TYPES = [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/webp',
|
||||
];
|
||||
|
||||
public function storeUploadedAsset(ContentType $contentType, UploadedFile $file, string $kind): string
|
||||
{
|
||||
$mime = strtolower((string) ($file->getMimeType() ?: ''));
|
||||
$extension = $this->safeExtension($file, $mime);
|
||||
$path = sprintf(
|
||||
'content-types/%d/%s-%s.%s',
|
||||
(int) $contentType->id,
|
||||
trim($kind) !== '' ? trim($kind) : 'asset',
|
||||
(string) Str::uuid(),
|
||||
$extension,
|
||||
);
|
||||
|
||||
$stream = fopen((string) ($file->getRealPath() ?: $file->getPathname()), 'rb');
|
||||
if ($stream === false) {
|
||||
throw new RuntimeException('Unable to open uploaded content type asset.');
|
||||
}
|
||||
|
||||
try {
|
||||
$written = Storage::disk($this->diskName())->put($path, $stream, [
|
||||
'visibility' => 'public',
|
||||
'CacheControl' => 'public, max-age=31536000, immutable',
|
||||
'ContentType' => $mime !== '' ? $mime : $this->mimeTypeForExtension($extension),
|
||||
]);
|
||||
} finally {
|
||||
fclose($stream);
|
||||
}
|
||||
|
||||
if ($written !== true) {
|
||||
throw new RuntimeException('Unable to store content type asset.');
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function deleteIfManaged(?string $path): void
|
||||
{
|
||||
$trimmed = trim((string) $path);
|
||||
|
||||
if ($trimmed === '' || str_starts_with($trimmed, 'http://') || str_starts_with($trimmed, 'https://') || str_starts_with($trimmed, '/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! str_starts_with($trimmed, 'content-types/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Storage::disk($this->diskName())->delete($trimmed);
|
||||
}
|
||||
|
||||
private function diskName(): string
|
||||
{
|
||||
return (string) config('uploads.object_storage.disk', 's3');
|
||||
}
|
||||
|
||||
private function safeExtension(UploadedFile $file, string $mime): string
|
||||
{
|
||||
$extension = strtolower((string) $file->getClientOriginalExtension());
|
||||
|
||||
if (! in_array($mime, self::ALLOWED_MIME_TYPES, true)) {
|
||||
throw new RuntimeException('Unsupported content type asset upload type.');
|
||||
}
|
||||
|
||||
return match ($extension) {
|
||||
'jpg', 'jpeg' => 'jpg',
|
||||
'png' => 'png',
|
||||
default => 'webp',
|
||||
};
|
||||
}
|
||||
|
||||
private function mimeTypeForExtension(string $extension): string
|
||||
{
|
||||
return match ($extension) {
|
||||
'jpg' => 'image/jpeg',
|
||||
'png' => 'image/png',
|
||||
default => 'image/webp',
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user