Completed
Push — master ( a0b650...225222 )
by Schlaefer
06:04 queued 03:08
created

MimeType::fixByFileExtension()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 3
nop 2
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace ImageUploader\Lib;
14
15
use Cake\Core\Configure;
16
use Cake\Filesystem\File;
17
18
/**
19
 * Determine mime-type for a file and try to fix some common mime-type issues.
20
 */
21
class MimeType
22
{
23
    /** @var array [<wrong type> => [<file .ext> => <right type>]] */
24
    private static $conversion = [
25
        'application/octet-stream' => [
26
            'mp4' => 'video/mp4',
27
        ],
28
    ];
29
30
    /**
31
     * Get mime-type
32
     *
33
     * @param string $filepath File path on server to check the actual file
34
     * @param string|null $name Original file name with original extension
35
     * @return string Determined mime-type
36
     */
37
    public static function get(string $filepath, ?string $name): string
38
    {
39
        $file = new File($filepath);
40
        if (!$file->exists()) {
41
            throw new \RuntimeException(
42
                sprintf('File "%s" does not exists.', $filepath),
43
                1570856931
44
            );
45
        }
46
47
        $type = $file->mime();
48
        if (!$type) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
49
            throw new \RuntimeException(
50
                sprintf('Cannot determine mime-type for file "%s".', $filepath),
51
                1570856932
52
            );
53
        }
54
55
        $name = $name ?: $file->pwd();
56
        $type = self::fixByFileExtension($type, $name);
57
58
        return $type;
59
    }
60
61
    /**
62
     * Fix type based on filename extension
63
     *
64
     * @param string $type original mime-type
65
     * @param string $filename path to file for filename
66
     * @return string fixed mime-type
67
     */
68
    private static function fixByFileExtension(string $type, string $filename): string
69
    {
70
        // Check that mime-type has an .extension based fix.
71
        if (array_key_exists($type, self::$conversion)) {
72
            $UploaderConfig = Configure::read('Saito.Settings.uploader');
73
            $fileExtension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
74
            $conversion = self::$conversion[$type];
75
            foreach ($conversion as $extension => $newType) {
76
                // Check that file has the matching .extension.
77
                if ($fileExtension !== $extension) {
78
                    continue;
79
                }
80
                // Check that the mime-type wich is considered a fix is allowed
81
                // at all.
82
                if (!$UploaderConfig->hasType($newType)) {
83
                    continue;
84
                }
85
                $type = $newType;
86
                break;
87
            }
88
        }
89
90
        return $type;
91
    }
92
}
93