Completed
Branch master (0964ce)
by Nazar
04:13
created

Mime::ensureDataLoaded()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4286
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
/**
4
 * LICENSE: This source code is subject to the license that is available
5
 * in the LICENSE file distributed along with this package.
6
 *
7
 * @package    Mime
8
 * @author     Matthew Caruana Galizia <[email protected]>
9
 * @copyright  Karwana Ltd
10
 * @since      File available since Release 1.0.0
11
 */
12
13
namespace Karwana\Mime;
14
15
class Mime {
16
17
	private static $mime_types;
18
19
	private static function ensureDataLoaded() {
20
		if (!isset(static::$mime_types)) {
21
			$json_path = implode(DIRECTORY_SEPARATOR, array(__DIR__, 'Resources', 'mime_types.json'));
22
			static::$mime_types = json_decode(file_get_contents($json_path), true);
23
		}
24
	}
25
26
27
	/**
28
	 * Get the MIME type associated with a given extension.
29
	 *
30
	 * @param string $extension A file extension e.g. pdf.
31
	 *
32
	 * @return string|null The associated MIME type or null if none found.
33
	 */
34
	public static function getTypeForExtension($extension) {
35
		static::ensureDataLoaded();
36
37
		$extension = strtolower($extension);
38
		foreach (static::$mime_types as $mime_type => $extensions) {
39
			if (is_array($extensions)) {
40
				if (in_array($extension, $extensions, true)) {
41
					return $mime_type;
42
				}
43
			} else if ($extension === $extensions) {
44
				return $mime_type;
45
			}
46
		}
47
	}
48
49
50
	/**
51
	 * Get the extension associated with a given MIME type.
52
	 *
53
	 * @param string $mime_type A MIME type e.g. application/pdf.
54
	 *
55
	 * @return string|null The first available associated extension or null if none found.
56
	 */
57
	public static function getExtensionForType($mime_type) {
58
		static::ensureDataLoaded();
59
60
		if (!static::hasType($mime_type)) {
61
			return;
62
		}
63
64
		$extensions = static::$mime_types[$mime_type];
65
		if (is_array($extensions)) {
66
			return $extensions[0];
67
		}
68
69
		return $extensions;
70
	}
71
72
73
	/**
74
	 * Get all the extensions associated with a given MIME type.
75
	 *
76
	 * @param string $mime_type A MIME type e.g. application/pdf.
77
	 *
78
	 * @return string[]|null An array of all the associated extensions or null if none found.
79
	 */
80
	public static function getExtensionsForType($mime_type) {
81
		static::ensureDataLoaded();
82
83
		if (static::hasType($mime_type)) {
84
			return (array) static::$mime_types[$mime_type];
85
		}
86
	}
87
88
89
	/**
90
	 * Check if an extension is known.
91
	 *
92
	 * @param string $extension An extension e.g. pdf.
93
	 *
94
	 * @return boolean
95
	 */
96
	public static function hasExtension($extension) {
97
		static::ensureDataLoaded();
98
99
		$extension = strtolower($extension);
100
		foreach (static::$mime_types as $extensions) {
101
			if (is_array($extensions)) {
102
				if (in_array($extension, $extensions, true)) {
103
					return true;
104
				}
105
			} else if ($extension === $extensions) {
106
				return true;
107
			}
108
		}
109
110
		return false;
111
	}
112
113
114
	/**
115
	 * Check if a MIME type is known.
116
	 *
117
	 * @param string $mime_type A MIME type e.g. application/pdf.
118
	 *
119
	 * @return boolean
120
	 */
121
	public static function hasType($mime_type) {
122
		static::ensureDataLoaded();
123
		return isset(static::$mime_types[$mime_type]);
124
	}
125
126
127
	/**
128
	 * Guess the MIME type of a given file, first by checking the extension then by falling back to magic.
129
	 *
130
	 * @param string $file_path Relative or absolute path to an existing file.
131
	 * @param string $reference_name Use this name for detection based on the extension.
132
	 * @param string $default Default MIME type.
133
	 *
134
	 * @return string|null The associated MIME type or the default if none found.
135
	 */
136
	public static function guessType($file_path, $reference_name = null, $default = 'application/octet-stream') {
137
		if (!$reference_name) {
138
			$reference_name = basename($file_path);
139
		}
140
141
		$extension = pathinfo($reference_name, PATHINFO_EXTENSION);
142
		if ($extension and $mime_type = static::getTypeForExtension($extension)) {
143
			return $mime_type;
144
		}
145
146
		// While it's true that the extension doesn't determine the type,
147
		// only use finfo as a fallback because it's bad at detecting text
148
		// types like CSS and JavaScript.
149
		if ($mime_type = static::getMagicType($file_path)) {
150
			return $mime_type;
151
		}
152
153
		return $default;
154
	}
155
156
157
	/**
158
	 * Guess the extension of a given file, first by checking the path then by falling back to magic.
159
	 *
160
	 * @param string $file_path Relative or absolute path to an existing file.
161
	 * @param string $reference_name Use this name for detection based on the extension.
162
	 * @param string $default Default extension.
163
	 *
164
	 * @return string|null The associated extension or the default if none found.
165
	 */
166
	public static function guessExtension($file_path, $reference_name = null, $default = 'bin') {
167
		if (!$reference_name) {
168
			$reference_name = basename($file_path);
169
		}
170
171
		if ($extension = pathinfo($reference_name, PATHINFO_EXTENSION) and static::hasExtension($extension)) {
172
			return strtolower($extension);
173
		}
174
175
		$mime_type = static::getMagicType($file_path);
176
		if ($mime_type and $extension = static::getExtensionForType($mime_type)) {
177
			return $extension;
178
		}
179
180
		return $default;
181
	}
182
183
184
	/**
185
	 * Get the MIME type of a file using magic.
186
	 *
187
	 * @param string $file_path Relative or absolute path to an existing file.
188
	 *
189
	 * @return string|null The associated MIME type or null if no known type was detected.
190
	 */
191
	public static function getMagicType($file_path) {
192
		$file_info = finfo_open(FILEINFO_MIME_TYPE);
193
		$mime_type = finfo_file($file_info, $file_path);
194
		finfo_close($file_info);
195
196
		// Only return valid types, in order to maintain circular compatibility between methods.
197
		if (static::hasType($mime_type)) {
198
			return $mime_type;
199
		}
200
	}
201
}
202