Skip to content
Advertisement

Add custom mimeType guesser in Laravel

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 
           */
    }
}

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement