From d18b37adcfe407757bce7be228d1ef6890305573 Mon Sep 17 00:00:00 2001 From: antoine Date: Fri, 23 Jan 2026 17:53:22 +0100 Subject: [PATCH 1/3] Add width / height in upload formatter --- .../Fields/Formatters/UploadFormatter.php | 31 ++++++++++++++++++- .../Fields/Formatters/UploadFormatterTest.php | 4 ++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Form/Fields/Formatters/UploadFormatter.php b/src/Form/Fields/Formatters/UploadFormatter.php index ec134d3a3..19562363f 100644 --- a/src/Form/Fields/Formatters/UploadFormatter.php +++ b/src/Form/Fields/Formatters/UploadFormatter.php @@ -6,6 +6,7 @@ use Code16\Sharp\Form\Fields\SharpFormUploadField; use Code16\Sharp\Utils\FileUtil; use Code16\Sharp\Utils\Uploads\SharpUploadManager; +use Illuminate\Filesystem\LocalFilesystemAdapter; use Illuminate\Support\Facades\Storage; class UploadFormatter extends SharpFieldFormatter implements FormatsAfterUpdate @@ -50,7 +51,7 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar 'filters' => $field->isImageTransformOriginal() ? null : $value['filters'] ?? null, - ]), function ($formatted) use ($field, $value) { + ]), function (&$formatted) use ($field, $value, $uploadedFieldRelativePath) { if ($field->storageDisk()) { app(SharpUploadManager::class)->queueHandleUploadedFile( uploadedFileName: $value['name'], @@ -63,6 +64,11 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar : null, ); } + + if ($size = $this->getImageSize($uploadedFieldRelativePath, $formatted['mime_type'])) { + $formatted['width'] = $size['width']; + $formatted['height'] = $size['height']; + } }); } @@ -108,4 +114,27 @@ protected function normalizeFromFront(?array $value, ?array $formatted = null): 'filters' => $formatted['filters'] ?? $value['filters'] ?? null, ])->whereNotNull()->toArray(); } + + protected function getImageSize(string $filePath, string $mimeType): ?array + { + // image size only available if tmp is stored locally + if (! Storage::disk(sharp()->config()->get('uploads.tmp_disk')) instanceof LocalFilesystemAdapter) { + return null; + } + + if (! str_starts_with($mimeType, 'image/')) { + return null; + } + + $realPath = Storage::disk(sharp()->config()->get('uploads.tmp_disk'))->path($filePath); + + if ($size = @getimagesize($realPath)) { + return [ + 'width' => $size[0], + 'height' => $size[1], + ]; + } + + return null; + } } diff --git a/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php b/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php index e2bc59cac..c8fc0c282 100644 --- a/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php +++ b/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php @@ -127,7 +127,7 @@ $formatter = app(UploadFormatter::class); UploadedFile::fake() - ->image('image.jpg') + ->image('image.jpg', width: 10, height: 10) ->storeAs('/tmp', 'image.jpg', ['disk' => 'local']); $field = SharpFormUploadField::make('upload')->setStorageTemporary(); @@ -144,5 +144,7 @@ 'disk' => 'local', 'mime_type' => 'image/jpeg', 'size' => 695, + 'width' => 10, + 'height' => 10, ]); }); From a291469acfbf14a081a36edd2351074b1c6f2590 Mon Sep 17 00:00:00 2001 From: antoine Date: Fri, 23 Jan 2026 18:13:13 +0100 Subject: [PATCH 2/3] rename for clarity --- src/Form/Fields/Formatters/UploadFormatter.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Form/Fields/Formatters/UploadFormatter.php b/src/Form/Fields/Formatters/UploadFormatter.php index 19562363f..ff6456a79 100644 --- a/src/Form/Fields/Formatters/UploadFormatter.php +++ b/src/Form/Fields/Formatters/UploadFormatter.php @@ -65,9 +65,9 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar ); } - if ($size = $this->getImageSize($uploadedFieldRelativePath, $formatted['mime_type'])) { - $formatted['width'] = $size['width']; - $formatted['height'] = $size['height']; + if ($dimensions = $this->getImageDimensions($uploadedFieldRelativePath, $formatted['mime_type'])) { + $formatted['width'] = $dimensions['width']; + $formatted['height'] = $dimensions['height']; } }); } @@ -115,7 +115,7 @@ protected function normalizeFromFront(?array $value, ?array $formatted = null): ])->whereNotNull()->toArray(); } - protected function getImageSize(string $filePath, string $mimeType): ?array + protected function getImageDimensions(string $tmpFilePath, string $mimeType): ?array { // image size only available if tmp is stored locally if (! Storage::disk(sharp()->config()->get('uploads.tmp_disk')) instanceof LocalFilesystemAdapter) { @@ -126,7 +126,7 @@ protected function getImageSize(string $filePath, string $mimeType): ?array return null; } - $realPath = Storage::disk(sharp()->config()->get('uploads.tmp_disk'))->path($filePath); + $realPath = Storage::disk(sharp()->config()->get('uploads.tmp_disk'))->path($tmpFilePath); if ($size = @getimagesize($realPath)) { return [ From 5e97c83347b2c6cb0cb172f524341e4275fd9df0 Mon Sep 17 00:00:00 2001 From: antoine Date: Fri, 30 Jan 2026 15:21:30 +0100 Subject: [PATCH 3/3] add more tests --- .../Eloquent/Uploads/SharpUploadModel.php | 5 +++ tests/Http/Form/FormEditorUploadsTest.php | 4 +++ .../Eloquent/Uploads/SharpUploadModelTest.php | 28 +++++++++++++++ .../Fields/Formatters/EditorFormatterTest.php | 2 ++ .../Fields/Formatters/UploadFormatterTest.php | 34 ++++++++++++++++--- 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/Form/Eloquent/Uploads/SharpUploadModel.php b/src/Form/Eloquent/Uploads/SharpUploadModel.php index 46c274f99..1c8b23dfc 100644 --- a/src/Form/Eloquent/Uploads/SharpUploadModel.php +++ b/src/Form/Eloquent/Uploads/SharpUploadModel.php @@ -7,6 +7,11 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Support\Facades\Storage; +/** + * @property array{crop:array{x:float,y:float,width:float,height:float},rotate:array{angle:int}} $filters + * @property ?int $width + * @property ?int $height + */ class SharpUploadModel extends Model { use FillsWithFileAttribute; diff --git a/tests/Http/Form/FormEditorUploadsTest.php b/tests/Http/Form/FormEditorUploadsTest.php index 6d0fbb14e..1735b3330 100644 --- a/tests/Http/Form/FormEditorUploadsTest.php +++ b/tests/Http/Form/FormEditorUploadsTest.php @@ -98,6 +98,8 @@ public function update($id, array $data) 'size' => 1367, 'mime_type' => 'image/jpeg', 'disk' => 'local', + 'width' => 200, + 'height' => 200, ])) ) ); @@ -187,6 +189,8 @@ public function update($id, array $data) 'size' => 1367, 'mime_type' => 'image/jpeg', 'disk' => 'local', + 'width' => 200, + 'height' => 200, ])) ) ); diff --git a/tests/Unit/Form/Eloquent/Uploads/SharpUploadModelTest.php b/tests/Unit/Form/Eloquent/Uploads/SharpUploadModelTest.php index 8324e4fa3..c96e5f191 100644 --- a/tests/Unit/Form/Eloquent/Uploads/SharpUploadModelTest.php +++ b/tests/Unit/Form/Eloquent/Uploads/SharpUploadModelTest.php @@ -15,6 +15,34 @@ Storage::fake('public'); }); +it('get correct attributes including custom properties', function () { + $upload = SharpUploadModel::create([ + 'file_name' => 'test/test.png', + 'size' => 120, + 'mime_type' => 'image/png', + 'disk' => 'local', + 'model_type' => Person::class, + 'model_id' => 1, + 'model_key' => 'test', + 'custom_properties' => [ + 'filters' => ['rotate' => ['angle' => 10]], + 'width' => 100, + 'height' => 100, + ], + ]); + expect($upload->file_name)->toBe('test/test.png') + ->and($upload->mime_type)->toBe('image/png') + ->and($upload->size)->toBe(120) + ->and($upload->disk)->toBe('local') + ->and($upload->model_type)->toBe(Person::class) + ->and($upload->model_id)->toBe(1) + ->and($upload->model_key)->toBe('test') + ->and($upload->custom_properties)->toEqual(['filters' => ['rotate' => ['angle' => 10]], 'width' => 100, 'height' => 100]) + ->and($upload->filters)->toBe(['rotate' => ['angle' => 10]]) + ->and($upload->width)->toBe(100) + ->and($upload->height)->toBe(100); +}); + it('fills several attributes at once at save with the magic "file" attribute', function () { $file = createImage(); $upload = createSharpUploadModel($file); diff --git a/tests/Unit/Form/Fields/Formatters/EditorFormatterTest.php b/tests/Unit/Form/Fields/Formatters/EditorFormatterTest.php index 0260fbcd6..55641466d 100644 --- a/tests/Unit/Form/Fields/Formatters/EditorFormatterTest.php +++ b/tests/Unit/Form/Fields/Formatters/EditorFormatterTest.php @@ -236,6 +236,8 @@ 'size' => 6467, 'mime_type' => 'image/jpeg', 'disk' => 'local', + 'width' => 600, + 'height' => 600, ])), e(json_encode([ 'file_name' => 'data/Posts/1/transformed.jpg', diff --git a/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php b/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php index c8fc0c282..173764b9b 100644 --- a/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php +++ b/tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php @@ -127,7 +127,7 @@ $formatter = app(UploadFormatter::class); UploadedFile::fake() - ->image('image.jpg', width: 10, height: 10) + ->image('image.jpg', width: 100, height: 100) ->storeAs('/tmp', 'image.jpg', ['disk' => 'local']); $field = SharpFormUploadField::make('upload')->setStorageTemporary(); @@ -143,8 +143,34 @@ 'file_name' => 'tmp/image.jpg', 'disk' => 'local', 'mime_type' => 'image/jpeg', - 'size' => 695, - 'width' => 10, - 'height' => 10, + 'size' => 887, + 'width' => 100, + 'height' => 100, + ]); +}); + +it('format image from front with width and height', function () { + $formatter = app(UploadFormatter::class); + + UploadedFile::fake() + ->image('image.jpg', width: 100, height: 100) + ->storeAs('/tmp', 'image.jpg', ['disk' => 'local']); + + $field = SharpFormUploadField::make('upload'); + + expect( + $formatter + ->fromFront($field, 'attr', [ + 'name' => 'image.jpg', + 'uploaded' => true, + ]) + ) + ->toEqual([ + 'file_name' => 'data/image.jpg', + 'disk' => 'local', + 'mime_type' => 'image/jpeg', + 'size' => 887, + 'width' => 100, + 'height' => 100, ]); });