|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace FileEye\MimeMap; |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* Class for managing the type-to-extension map. |
|
7
|
|
|
*/ |
|
8
|
|
|
class MapHandler |
|
9
|
|
|
{ |
|
10
|
|
|
/** |
|
11
|
|
|
* Mapping between file extensions and MIME types. |
|
12
|
|
|
* |
|
13
|
|
|
* The array has two main keys, 'types' that maps MIME types to file |
|
14
|
|
|
* extensions, and 'extensions' that map file extensions to MIME types. |
|
15
|
|
|
* |
|
16
|
|
|
* @var array |
|
17
|
|
|
*/ |
|
18
|
|
|
protected $map; |
|
19
|
|
|
|
|
20
|
|
|
/** |
|
21
|
|
|
* Constructor. |
|
22
|
|
|
* |
|
23
|
|
|
* @param array $map |
|
24
|
|
|
* (Optional) The mapping to be used for this instance. If null, the |
|
25
|
|
|
* default map will be used. |
|
26
|
|
|
*/ |
|
27
|
17 |
|
public function __construct(array $map = null) |
|
28
|
|
|
{ |
|
29
|
17 |
|
if (is_null($map)) { |
|
30
|
17 |
|
$this->map = &TypeExtensionMap::$map; |
|
31
|
|
|
} else { |
|
32
|
|
|
$this->map = $map; |
|
33
|
|
|
} |
|
34
|
17 |
|
} |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* Returns the map associated with this instance. |
|
38
|
|
|
* |
|
39
|
|
|
* @return array |
|
40
|
|
|
*/ |
|
41
|
13 |
|
public function get() |
|
42
|
|
|
{ |
|
43
|
13 |
|
return $this->map; |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* Sorts the map. |
|
48
|
|
|
* |
|
49
|
|
|
* @return $this |
|
50
|
|
|
*/ |
|
51
|
1 |
|
public function sort() |
|
52
|
|
|
{ |
|
53
|
1 |
|
ksort($this->map['types']); |
|
54
|
1 |
|
ksort($this->map['extensions']); |
|
55
|
1 |
|
return $this; |
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* Adds an entry to the map. |
|
60
|
|
|
* |
|
61
|
|
|
* Checks that no duplicate entries are made. |
|
62
|
|
|
* |
|
63
|
|
|
* @param string $key |
|
64
|
|
|
* The main array key. |
|
65
|
|
|
* @param string $entry |
|
66
|
|
|
* The sub array key. |
|
67
|
|
|
* @param string $value |
|
68
|
|
|
* The value to add. |
|
69
|
|
|
* |
|
70
|
|
|
* @return $this |
|
71
|
|
|
*/ |
|
72
|
2 |
|
protected function addMapEntry($key, $entry, $value) |
|
73
|
|
|
{ |
|
74
|
2 |
|
if (!isset($this->map[$key][$entry])) { |
|
75
|
2 |
|
$this->map[$key][$entry] = [$value]; |
|
76
|
|
|
} else { |
|
77
|
1 |
|
if (array_search($value, $this->map[$key][$entry]) === false) { |
|
78
|
|
|
$this->map[$key][$entry][] = $value; |
|
79
|
|
|
} |
|
80
|
|
|
} |
|
81
|
2 |
|
return $this; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* Removes an entry from the map. |
|
86
|
|
|
* |
|
87
|
|
|
* @param string $key |
|
88
|
|
|
* The main array key. |
|
89
|
|
|
* @param string $entry |
|
90
|
|
|
* The sub array key. |
|
91
|
|
|
* @param string $value |
|
92
|
|
|
* The value. |
|
93
|
|
|
* |
|
94
|
|
|
* @return bool |
|
95
|
|
|
* true if the entry was removed, false if the entry was not present. |
|
96
|
|
|
*/ |
|
97
|
1 |
|
protected function removeMapEntry($key, $entry, $value) |
|
98
|
|
|
{ |
|
99
|
|
|
// Return false if no entry. |
|
100
|
1 |
|
if (!isset($this->map[$key][$entry])) { |
|
101
|
1 |
|
return false; |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
// Return false if no value. |
|
105
|
1 |
|
$k = array_search($value, $this->map[$key][$entry]); |
|
106
|
1 |
|
if ($k === false) { |
|
107
|
|
|
return false; |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
// Remove the map entry. |
|
111
|
1 |
|
unset($this->map[$key][$entry][$k]); |
|
112
|
|
|
|
|
113
|
|
|
// Remove the entry itself if no more values. |
|
114
|
1 |
|
if (empty($this->map[$key][$entry])) { |
|
115
|
1 |
|
unset($this->map[$key][$entry]); |
|
116
|
|
|
} else { |
|
117
|
|
|
// Resequence the remaining values. |
|
118
|
1 |
|
$tmp = []; |
|
119
|
1 |
|
foreach ($this->map[$key][$entry] as $v) { |
|
120
|
1 |
|
$tmp[] = $v; |
|
121
|
|
|
} |
|
122
|
1 |
|
$this->map[$key][$entry] = $tmp; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
1 |
|
return true; |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/** |
|
129
|
|
|
* Adds a type-to-extension mapping. |
|
130
|
|
|
* |
|
131
|
|
|
* @param string $type |
|
132
|
|
|
* A MIME type. |
|
133
|
|
|
* @param string $extension |
|
134
|
|
|
* A file extension. |
|
135
|
|
|
* |
|
136
|
|
|
* @return $this |
|
137
|
|
|
*/ |
|
138
|
2 |
|
public function addMapping($type, $extension) |
|
139
|
|
|
{ |
|
140
|
2 |
|
$type = strtolower($type); |
|
141
|
2 |
|
$extension = (string) strtolower($extension); |
|
142
|
|
|
|
|
143
|
|
|
// Add entry to 'types'. |
|
144
|
2 |
|
$this->addMapEntry('types', $type, $extension); |
|
145
|
|
|
|
|
146
|
|
|
// Add entry to 'extensions'. |
|
147
|
2 |
|
$this->addMapEntry('extensions', $extension, $type); |
|
148
|
|
|
|
|
149
|
2 |
|
return $this; |
|
150
|
|
|
} |
|
151
|
|
|
|
|
152
|
|
|
/** |
|
153
|
|
|
* Removes a type-to-extension mapping. |
|
154
|
|
|
* |
|
155
|
|
|
* @param string $type |
|
156
|
|
|
* A MIME type. |
|
157
|
|
|
* @param string $extension |
|
158
|
|
|
* A file extension. |
|
159
|
|
|
* |
|
160
|
|
|
* @return bool |
|
161
|
|
|
* true if the mapping was removed, false if the mapping was not present. |
|
162
|
|
|
*/ |
|
163
|
1 |
|
public function removeMapping($type, $extension) |
|
164
|
|
|
{ |
|
165
|
1 |
|
$type = strtolower($type); |
|
166
|
1 |
|
$extension = (string) strtolower($extension); |
|
167
|
|
|
|
|
168
|
|
|
// Remove entry from 'types'. |
|
169
|
1 |
|
$type_ret = $this->removeMapEntry('types', $type, $extension); |
|
170
|
|
|
|
|
171
|
|
|
// Remove entry from 'extensions'. |
|
172
|
1 |
|
$extension_ret = $this->removeMapEntry('extensions', $extension, $type); |
|
173
|
|
|
|
|
174
|
1 |
|
return $type_ret && $extension_ret; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Removes the entire mapping of a type. |
|
179
|
|
|
* |
|
180
|
|
|
* @param string $type |
|
181
|
|
|
* A MIME type. |
|
182
|
|
|
* |
|
183
|
|
|
* @return bool |
|
184
|
|
|
* true if the mapping was removed, false if the type was not present. |
|
185
|
|
|
*/ |
|
186
|
1 |
|
public function removeType($type) |
|
187
|
|
|
{ |
|
188
|
1 |
|
$type = strtolower($type); |
|
189
|
|
|
|
|
190
|
|
|
// Return false if type is not found. |
|
191
|
1 |
|
if (!isset($this->map['types'][$type])) { |
|
192
|
1 |
|
return false; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
// Loop through all the associated extensions and remove them. This |
|
196
|
|
|
// is also removing the type itself when the last extension is removed. |
|
197
|
1 |
|
foreach ($this->map['types'][$type] as $extension) { |
|
198
|
1 |
|
$this->removeMapping($type, $extension); |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
1 |
|
return true; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
/** |
|
205
|
|
|
* Changes the default extension for a MIME type. |
|
206
|
|
|
* |
|
207
|
|
|
* @param string $type |
|
208
|
|
|
* A MIME type. |
|
209
|
|
|
* @param string $extension |
|
210
|
|
|
* A file extension. |
|
211
|
|
|
* |
|
212
|
|
|
* @throws MappingException if no mapping found. |
|
213
|
|
|
* |
|
214
|
|
|
* @return $this |
|
215
|
|
|
*/ |
|
216
|
3 |
View Code Duplication |
public function setTypeDefaultExtension($type, $extension) |
|
|
|
|
|
|
217
|
|
|
{ |
|
218
|
3 |
|
$type = strtolower($type); |
|
219
|
3 |
|
$extension = (string) strtolower($extension); |
|
220
|
|
|
|
|
221
|
3 |
|
if (!isset($this->map['types'][$type])) { |
|
222
|
1 |
|
throw new MappingException('Cannot set ' . $extension . ' as default extension for type ' . $type . ', type not defined'); |
|
223
|
|
|
} |
|
224
|
2 |
|
$key = array_search($extension, $this->map['types'][$type]); |
|
225
|
2 |
|
if ($key === false) { |
|
226
|
1 |
|
throw new MappingException('Cannot set ' . $extension . ' as default extension for type ' . $type . ', extension not associated to this type'); |
|
227
|
|
|
} |
|
228
|
1 |
|
$tmp = [$extension]; |
|
229
|
1 |
|
foreach ($this->map['types'][$type] as $k => $v) { |
|
230
|
1 |
|
if ($k === $key) { |
|
231
|
1 |
|
continue; |
|
232
|
|
|
} |
|
233
|
1 |
|
$tmp[] = $v; |
|
234
|
|
|
} |
|
235
|
1 |
|
$this->map['types'][$type] = $tmp; |
|
236
|
1 |
|
return $this; |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
/** |
|
240
|
|
|
* Changes the default MIME type for a file extension. |
|
241
|
|
|
* |
|
242
|
|
|
* @param string $extension |
|
243
|
|
|
* A file extension. |
|
244
|
|
|
* @param string $type |
|
245
|
|
|
* A MIME type. |
|
246
|
|
|
* |
|
247
|
|
|
* @throws MappingException if no mapping found. |
|
248
|
|
|
* |
|
249
|
|
|
* @return $this |
|
250
|
|
|
*/ |
|
251
|
3 |
View Code Duplication |
public function setExtensionDefaultType($extension, $type) |
|
|
|
|
|
|
252
|
|
|
{ |
|
253
|
3 |
|
$type = strtolower($type); |
|
254
|
3 |
|
$extension = (string) strtolower($extension); |
|
255
|
|
|
|
|
256
|
3 |
|
if (!isset($this->map['extensions'][$extension])) { |
|
257
|
1 |
|
throw new MappingException('Cannot set ' . $type . ' as default type for extension ' . $extension . ', extension not defined'); |
|
258
|
|
|
} |
|
259
|
2 |
|
$key = array_search($type, $this->map['extensions'][$extension]); |
|
260
|
2 |
|
if ($key === false) { |
|
261
|
1 |
|
throw new MappingException('Cannot set ' . $type . ' as default type for extension ' . $extension . ', type not associated to this extension'); |
|
262
|
|
|
} |
|
263
|
1 |
|
$tmp = [$type]; |
|
264
|
1 |
|
foreach ($this->map['extensions'][$extension] as $k => $v) { |
|
265
|
1 |
|
if ($k === $key) { |
|
266
|
1 |
|
continue; |
|
267
|
|
|
} |
|
268
|
1 |
|
$tmp[] = $v; |
|
269
|
|
|
} |
|
270
|
1 |
|
$this->map['extensions'][$extension] = $tmp; |
|
271
|
1 |
|
return $this; |
|
272
|
|
|
} |
|
273
|
|
|
} |
|
274
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.