Skip to content

Commit ee499c1

Browse files
committed
Fix base64-encoded image files for asset creation; add test
1 parent 6cf88b1 commit ee499c1

File tree

3 files changed

+31
-10
lines changed

3 files changed

+31
-10
lines changed

app/Http/Requests/StoreAssetRequest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function authorize(): bool
2626

2727
public function prepareForValidation(): void
2828
{
29+
parent::prepareForValidation(); // call ImageUploadRequest thing
2930
// Guard against users passing in an array for company_id instead of an integer.
3031
// If the company_id is not an integer then we simply use what was
3132
// provided to be caught by model level validation later.

app/Http/Traits/ConvertsBase64ToFiles.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Http\Traits;
44

5+
use Illuminate\Validation\ValidationException;
56
use Illuminate\Http\UploadedFile;
67
use Illuminate\Support\Arr;
78
use Illuminate\Support\Collection;
@@ -38,28 +39,22 @@ protected function prepareForValidation()
3839
if (!$base64Contents) {
3940
return;
4041
}
41-
42-
// autogenerate filenames
43-
if ($filename == 'auto'){
44-
$header = explode(';', $base64Contents, 2)[0];
45-
// Grab the image type from the header while we're at it.
46-
$filename = $key . '.' . substr($header, strpos($header, '/')+1);
47-
}
4842

4943
// Generate a temporary path to store the Base64 contents
5044
$tempFilePath = tempnam(sys_get_temp_dir(), $filename);
5145

52-
// Store the contents using a stream, or by decoding manually
46+
// Store the contents using a stream, or throw an Error (which doesn't do anything?)
5347
if (Str::startsWith($base64Contents, 'data:') && count(explode(',', $base64Contents)) > 1) {
54-
$source = fopen($base64Contents, 'r');
48+
$source = fopen($base64Contents, 'r'); // PHP has special processing for "data:" URL's
5549
$destination = fopen($tempFilePath, 'w');
5650

5751
stream_copy_to_stream($source, $destination);
5852

5953
fclose($source);
6054
fclose($destination);
6155
} else {
62-
file_put_contents($tempFilePath, base64_decode($base64Contents, true));
56+
// TODO - to get a better error message here, can we maybe do something with modifying the errorBag?
57+
throw new ValidationException("Need Base64 URL starting with 'data:'"); // This doesn't actually throw?
6358
}
6459

6560
$uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true);

tests/Feature/Assets/Api/StoreAssetTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use App\Models\Supplier;
1212
use App\Models\User;
1313
use Illuminate\Support\Facades\Crypt;
14+
use Illuminate\Support\Facades\Storage;
1415
use Illuminate\Testing\Fluent\AssertableJson;
1516
use PHPUnit\Framework\Attributes\DataProvider;
1617
use Tests\TestCase;
@@ -831,4 +832,28 @@ public function testPermissionNeededToStoreEncryptedField()
831832
$asset = Asset::findOrFail($response['payload']['id']);
832833
$this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()}));
833834
}
835+
836+
public function testBase64AssetImages()
837+
{
838+
$status = Statuslabel::factory()->readyToDeploy()->create();
839+
$model = AssetModel::factory()->create();
840+
$superuser = User::factory()->superuser()->create();
841+
842+
$response = $this->actingAsForApi($superuser)
843+
->postJson(route('api.assets.store'), [
844+
'model_id' => $model->id,
845+
'status_id' => $status->id,
846+
'asset_tag' => '1234',
847+
'image' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsAQMAAADXeXeBAAAABlBMVEX+AAD///+KQee0AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH5QQbCAoNcoiTQAAAACZJREFUaN7twTEBAAAAwqD1T20JT6AAAAAAAAAAAAAAAAAAAICnATvEAAEnf54JAAAAAElFTkSuQmCC'
848+
])
849+
->assertStatusMessageIs('success')
850+
->assertOk()
851+
->json();
852+
853+
$asset = Asset::findOrFail($response['payload']['id']);
854+
$this->assertEquals($asset->asset_tag, '1234');
855+
$image_data = Storage::disk('public')->get(app('assets_upload_path') . e($asset->image));
856+
//$this->assertEquals('3d67fb99a0b6926e350f7b71397525d7a6b936c1', sha1($image_data)); //this doesn't work because the image gets resized - use the resized hash instead
857+
$this->assertEquals('db2e13ba04318c99058ca429d67777322f48566b', sha1($image_data));
858+
}
834859
}

0 commit comments

Comments
 (0)