From c1b28159b2b2450e2de86954aea3a4b7bdac0300 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Thu, 23 Jul 2026 11:23:05 -0300 Subject: [PATCH] refactor: split HasMedia path storage into image vs stream helpers Keep the image-normalize vs binary-stream split, but move each path into a focused private method so addMediaFromPath stays linear. Co-authored-by: Cursor --- app/Models/Traits/HasMedia.php | 101 ++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/app/Models/Traits/HasMedia.php b/app/Models/Traits/HasMedia.php index a49af10f..da4b39eb 100644 --- a/app/Models/Traits/HasMedia.php +++ b/app/Models/Traits/HasMedia.php @@ -107,7 +107,7 @@ public function addMedia(UploadedFile $file, string $collection = 'default', arr /** * Add media from a file path (used for chunked uploads). - * Non-images are streamed to storage instead of loaded into memory. + * Images are normalized in memory; videos/PDFs are streamed to storage. */ public function addMediaFromPath(string $filePath, string $originalFilename, string $collection = 'default', array $meta = [], ?string $groupId = null): Media { @@ -119,50 +119,20 @@ public function addMediaFromPath(string $filePath, string $originalFilename, str $type = $this->getMediaType($mimeType); $extension = pathinfo($originalFilename, PATHINFO_EXTENSION); - if ($type === Type::Image->value) { - [$bytes, $storedMime, $storedExt] = $this->normalizeImageFormat( - $filePath, - $mimeType, - $type, - $extension, - ); - $size = strlen($bytes); - $mediaMeta = array_merge($this->getMediaMetaFromBytes($bytes, $type, $meta), $meta); - $filename = Str::uuid().".{$storedExt}"; - $storagePath = "medias/{$filename}"; - Storage::put($storagePath, $bytes); - } else { - $storedMime = $mimeType; - $storedExt = $extension; - $size = (int) filesize($filePath); - $mediaMeta = $meta; - $filename = Str::uuid().".{$storedExt}"; - $storagePath = "medias/{$filename}"; - $stream = fopen($filePath, 'rb'); - - if ($stream === false) { - throw new RuntimeException("Unable to open media file for reading: {$filePath}"); - } - - try { - Storage::writeStream($storagePath, $stream); - } finally { - if (is_resource($stream)) { - fclose($stream); - } - } - } + $stored = $type === Type::Image->value + ? $this->storeImageFromPath($filePath, $mimeType, $type, $extension, $meta) + : $this->streamFileToStorage($filePath, $mimeType, $extension, $meta); return $this->media()->create([ 'group_id' => $groupId ?? Str::uuid()->toString(), 'collection' => $collection, 'type' => $type, - 'path' => $storagePath, + 'path' => $stored['path'], 'original_filename' => $originalFilename, - 'mime_type' => $storedMime, - 'size' => $size, + 'mime_type' => $stored['mime_type'], + 'size' => $stored['size'], 'order' => 0, - 'meta' => $mediaMeta, + 'meta' => $stored['meta'], ]); } @@ -211,6 +181,61 @@ public function isSingleMediaCollection(string $collection): bool return $config === 'single'; } + /** + * @param array $meta + * @return array{path: string, mime_type: string, size: int, meta: array} + */ + private function storeImageFromPath(string $filePath, string $mimeType, string $type, string $extension, array $meta): array + { + [$bytes, $storedMime, $storedExt] = $this->normalizeImageFormat( + $filePath, + $mimeType, + $type, + $extension, + ); + + $filename = Str::uuid().".{$storedExt}"; + $path = "medias/{$filename}"; + Storage::put($path, $bytes); + + return [ + 'path' => $path, + 'mime_type' => $storedMime, + 'size' => strlen($bytes), + 'meta' => array_merge($this->getMediaMetaFromBytes($bytes, $type, $meta), $meta), + ]; + } + + /** + * @param array $meta + * @return array{path: string, mime_type: string, size: int, meta: array} + */ + private function streamFileToStorage(string $filePath, string $mimeType, string $extension, array $meta): array + { + $filename = Str::uuid().".{$extension}"; + $path = "medias/{$filename}"; + $stream = fopen($filePath, 'rb'); + + if ($stream === false) { + throw new RuntimeException("Unable to open media file for reading: {$filePath}"); + } + + try { + Storage::writeStream($path, $stream); + } finally { + if (is_resource($stream)) { + fclose($stream); + } + } + + return [ + 'path' => $path, + 'mime_type' => $mimeType, + 'size' => (int) filesize($filePath), + 'meta' => $meta, + ]; + } + private function getMediaType(string $mimeType): string { return (Type::classify($mimeType)