I am trying to upload a file in .imed
format. It is rare format and Laravel detect it as application/zip
which is fine. But beside that Laravel saves my file as hash_name.zip
When I try to get file extension of uploaded file by:
var_dump($data['file_uri']->extension());
I got string(3) "zip"
I made some research and I found that Laravel is using Symfony MimeType component to guess the mimetype of file. I don’t know if this is possible, but in Symfony docs there is a section about registering custom MimeTypeGuesser. Instruction are for Symfony and they might be not applicable for Laravel.
The other solution for my problem would be renaming file after saving it on the server from hash_name.zip to hash_name.imed
Some of my code responsible for uploading a file:
class ScanRepository implements ScanInterface { public function createScan(array $data) { $scan = new Scan(); $scan->file_uri = "/storage/scans/" . $data['file_uri']->hashName(); $scan->save(); }
Registered Observer
class ScanObserver { /** * Handle the scan "created" event. * * @param Scan $scan * @return void */ public function created(Scan $scan) { Storage::disk('scans')->putFileAs('', request()->file('file_uri'), basename($scan->file_uri)); }
Upload functionality works, but saves my data on different file extension.
Advertisement
Answer
I ended up with this kind of solution:
public function createScan(array $data) { $scan = new Scan(); $hash = $data['file_uri']->hashName(); // We have to override filename extension to .iMed, because Laravel detects it as .zip $scan->file_uri = "/storage/scans/" . preg_replace('/..+$/', '.' . 'iMed', $hash); $scan->save(); }
Might be not the best elegant, but it works.
I have also tried to register CustomMimeTypeGuesser by using
MimeTypes::getDefault()->registerGuesser(new CustomMimeTypeGuesser());
And creating a custom guesser that implements
class CustomMimeTypeGuesser implements MimeTypeGuesserInterface { public function isGuesserSupported(): bool { return true; } public function guessMimeType(string $path): ?string { /* Returning here a string .imed doesn't give anything because Symfony MimeType component still try to map mimetype to file extension. So if he doesn't not now anything about .imed he will return null at the end */ } }