Skip to content

Commit e5f52de

Browse files
authored
Merge pull request #696 from code16/store-image-dimension
Allow to store image dimensions
2 parents 03f5894 + 5e97c83 commit e5f52de

6 files changed

Lines changed: 99 additions & 3 deletions

File tree

src/Form/Eloquent/Uploads/SharpUploadModel.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use Illuminate\Database\Eloquent\Relations\MorphTo;
88
use Illuminate\Support\Facades\Storage;
99

10+
/**
11+
* @property array{crop:array{x:float,y:float,width:float,height:float},rotate:array{angle:int}} $filters
12+
* @property ?int $width
13+
* @property ?int $height
14+
*/
1015
class SharpUploadModel extends Model
1116
{
1217
use FillsWithFileAttribute;

src/Form/Fields/Formatters/UploadFormatter.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Code16\Sharp\Form\Fields\SharpFormUploadField;
77
use Code16\Sharp\Utils\FileUtil;
88
use Code16\Sharp\Utils\Uploads\SharpUploadManager;
9+
use Illuminate\Filesystem\LocalFilesystemAdapter;
910
use Illuminate\Support\Facades\Storage;
1011

1112
class UploadFormatter extends SharpFieldFormatter implements FormatsAfterUpdate
@@ -50,7 +51,7 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar
5051
'filters' => $field->isImageTransformOriginal()
5152
? null
5253
: $value['filters'] ?? null,
53-
]), function ($formatted) use ($field, $value) {
54+
]), function (&$formatted) use ($field, $value, $uploadedFieldRelativePath) {
5455
if ($field->storageDisk()) {
5556
app(SharpUploadManager::class)->queueHandleUploadedFile(
5657
uploadedFileName: $value['name'],
@@ -63,6 +64,11 @@ public function fromFront(SharpFormField $field, string $attribute, $value): ?ar
6364
: null,
6465
);
6566
}
67+
68+
if ($dimensions = $this->getImageDimensions($uploadedFieldRelativePath, $formatted['mime_type'])) {
69+
$formatted['width'] = $dimensions['width'];
70+
$formatted['height'] = $dimensions['height'];
71+
}
6672
});
6773
}
6874

@@ -108,4 +114,27 @@ protected function normalizeFromFront(?array $value, ?array $formatted = null):
108114
'filters' => $formatted['filters'] ?? $value['filters'] ?? null,
109115
])->whereNotNull()->toArray();
110116
}
117+
118+
protected function getImageDimensions(string $tmpFilePath, string $mimeType): ?array
119+
{
120+
// image size only available if tmp is stored locally
121+
if (! Storage::disk(sharp()->config()->get('uploads.tmp_disk')) instanceof LocalFilesystemAdapter) {
122+
return null;
123+
}
124+
125+
if (! str_starts_with($mimeType, 'image/')) {
126+
return null;
127+
}
128+
129+
$realPath = Storage::disk(sharp()->config()->get('uploads.tmp_disk'))->path($tmpFilePath);
130+
131+
if ($size = @getimagesize($realPath)) {
132+
return [
133+
'width' => $size[0],
134+
'height' => $size[1],
135+
];
136+
}
137+
138+
return null;
139+
}
111140
}

tests/Http/Form/FormEditorUploadsTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public function update($id, array $data)
9898
'size' => 1367,
9999
'mime_type' => 'image/jpeg',
100100
'disk' => 'local',
101+
'width' => 200,
102+
'height' => 200,
101103
]))
102104
)
103105
);
@@ -187,6 +189,8 @@ public function update($id, array $data)
187189
'size' => 1367,
188190
'mime_type' => 'image/jpeg',
189191
'disk' => 'local',
192+
'width' => 200,
193+
'height' => 200,
190194
]))
191195
)
192196
);

tests/Unit/Form/Eloquent/Uploads/SharpUploadModelTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,34 @@
1515
Storage::fake('public');
1616
});
1717

18+
it('get correct attributes including custom properties', function () {
19+
$upload = SharpUploadModel::create([
20+
'file_name' => 'test/test.png',
21+
'size' => 120,
22+
'mime_type' => 'image/png',
23+
'disk' => 'local',
24+
'model_type' => Person::class,
25+
'model_id' => 1,
26+
'model_key' => 'test',
27+
'custom_properties' => [
28+
'filters' => ['rotate' => ['angle' => 10]],
29+
'width' => 100,
30+
'height' => 100,
31+
],
32+
]);
33+
expect($upload->file_name)->toBe('test/test.png')
34+
->and($upload->mime_type)->toBe('image/png')
35+
->and($upload->size)->toBe(120)
36+
->and($upload->disk)->toBe('local')
37+
->and($upload->model_type)->toBe(Person::class)
38+
->and($upload->model_id)->toBe(1)
39+
->and($upload->model_key)->toBe('test')
40+
->and($upload->custom_properties)->toEqual(['filters' => ['rotate' => ['angle' => 10]], 'width' => 100, 'height' => 100])
41+
->and($upload->filters)->toBe(['rotate' => ['angle' => 10]])
42+
->and($upload->width)->toBe(100)
43+
->and($upload->height)->toBe(100);
44+
});
45+
1846
it('fills several attributes at once at save with the magic "file" attribute', function () {
1947
$file = createImage();
2048
$upload = createSharpUploadModel($file);

tests/Unit/Form/Fields/Formatters/EditorFormatterTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@
236236
'size' => 6467,
237237
'mime_type' => 'image/jpeg',
238238
'disk' => 'local',
239+
'width' => 600,
240+
'height' => 600,
239241
])),
240242
e(json_encode([
241243
'file_name' => 'data/Posts/1/transformed.jpg',

tests/Unit/Form/Fields/Formatters/UploadFormatterTest.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
$formatter = app(UploadFormatter::class);
128128

129129
UploadedFile::fake()
130-
->image('image.jpg')
130+
->image('image.jpg', width: 100, height: 100)
131131
->storeAs('/tmp', 'image.jpg', ['disk' => 'local']);
132132

133133
$field = SharpFormUploadField::make('upload')->setStorageTemporary();
@@ -143,6 +143,34 @@
143143
'file_name' => 'tmp/image.jpg',
144144
'disk' => 'local',
145145
'mime_type' => 'image/jpeg',
146-
'size' => 695,
146+
'size' => 887,
147+
'width' => 100,
148+
'height' => 100,
149+
]);
150+
});
151+
152+
it('format image from front with width and height', function () {
153+
$formatter = app(UploadFormatter::class);
154+
155+
UploadedFile::fake()
156+
->image('image.jpg', width: 100, height: 100)
157+
->storeAs('/tmp', 'image.jpg', ['disk' => 'local']);
158+
159+
$field = SharpFormUploadField::make('upload');
160+
161+
expect(
162+
$formatter
163+
->fromFront($field, 'attr', [
164+
'name' => 'image.jpg',
165+
'uploaded' => true,
166+
])
167+
)
168+
->toEqual([
169+
'file_name' => 'data/image.jpg',
170+
'disk' => 'local',
171+
'mime_type' => 'image/jpeg',
172+
'size' => 887,
173+
'width' => 100,
174+
'height' => 100,
147175
]);
148176
});

0 commit comments

Comments
 (0)