mtmacdonald
mtmacdonald

Reputation: 15070

Replacement for File::mime() in Laravel 4 (to get mime type from file extension)

Laravel 3 had a File::mime() method which made it easy to get a file's mime type from its extension:

$extension = File::extension($path);
$mime = File::mime($extension);

On upgrading to Laravel 4 I get an error:

Call to undefined method Illuminate\Filesystem\Filesystem::mime()

I also can't see any mention of mime types in the Filesystem API docs.

What's the recommended way to get a file's mime type in Laravel 4 (please note this is not a user-uploaded file)?

Upvotes: 10

Views: 25260

Answers (5)

itsazzad
itsazzad

Reputation: 7277

public function mimeType($path)
{
    return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
}

Ref: https://github.com/illuminate/filesystem/blob/master/Filesystem.php#L194

Upvotes: 1

kovpack
kovpack

Reputation: 5045

It turned out that Symfony ExtensionGuesser and MimeTypeGuesser use unreliable FileInfo class. For that reason validation of mimes return unpredictable results and can not be used with files uploads in a proper way (it returns text/plain mime for js, xls, po etc.).

I've found very simple solution for this problem.

Instead of

'attachment' => 'required|mimes:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt|max:10000',

I split that into two different parts and now my validation looks like this:

private function createFileAttachmentValidator($file)
{
    return Validator::make(
        [
            'attachment' => $file,
            'extension'  => \Str::lower($file->getClientOriginalExtension()),
        ],
        [
            'attachment' => 'required|max:10000',
            'extension'  => 'required|in:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt',
        ],
        $this->validationMessages()
    );          
}   

I simply try to verify that extension of the file is present and that it is listed in my in rule. That works, however, solution is not perfect.

Upvotes: 2

mtmacdonald
mtmacdonald

Reputation: 15070

After reading that:

I decided instead to port Laravel 3's implementation of File::mime() into a helper library within my Laravel 4 application. The Laravel 3 implementation just reads the MIME types from a config lookup array, based on file extension.

Solution:

  • Copied application/config/mimes.php from my L3 project to app/config/mimes.php in my L4 project
  • Made a FileHelper library with the File::mime() function code from the Laravel 3 File class.

Upvotes: 6

Dennis Braga
Dennis Braga

Reputation: 1478

IF you had just uploaded the file you can use:

Input::file('field_name')->getMimeType();

You can see more here! I hope it be for some help! :D

EDIT:
Input::file is some kind of extention from File, so you may use File::get('file')->getMimeType(); also. Didn't test, but MUST work.

Upvotes: 7

mtmacdonald
mtmacdonald

Reputation: 15070

One solution I've found is to use the Symfony HttpFoundation File class (which is already included as a dependency in Laravel 4):

$file = new Symfony\Component\HttpFoundation\File\File($path);
$mime = $file->getMimeType();

And in fact the File class uses the Symfony MimeTypeGuesser class so this also works:

$guesser = Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser::getInstance();
echo $guesser->guess($path);

But unfortunately I'm getting unexpected results: I'm getting text/plain instead of text/css when passing a path to a css file.

Upvotes: 18

Related Questions