Passed
Pull Request — master (#9)
by mon
02:04
created

AbstractMap::getMapArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace FileEye\MimeMap\Map;
4
5
use FileEye\MimeMap\MappingException;
6
7
/**
8
 * Abstract class for mapping file extensions to MIME types.
9
 *
10
 * This class cannot be instantiated; extend from it to implement a map.
11
 */
12
abstract class AbstractMap
13
{
14
    /**
15
     * Returns the singleton.
16
     *
17
     * @return string
18
     */
19 24
    public static function getInstance()
20
    {
21 24
        if (!static::$instance) {
22 3
            static::$instance = new static();
23
        }
24 24
        return static::$instance;
25
    }
26
27
    /**
28
     * Returns this file's full qualified filename.
29
     *
30
     * @return string
31
     */
32
    public function getFileName()
33
    {
34
        throw new \LogicException(__METHOD__ . ' is not implemented in ' . get_called_class());
35
    }
36
37
    /**
38
     * Gets the map array.
39
     *
40
     * @return array
41
     */
42 3
    public function getMapArray()
43
    {
44 3
        return static::$map;
45
    }
46
47
    /**
48
     * Sorts the map.
49
     *
50
     * @return $this
51
     */
52 1
    public function sort()
53
    {
54 1
        ksort(static::$map['types']);
55 1
        ksort(static::$map['extensions']);
56 1
        return $this;
57
    }
58
59
    /**
60
     * Lists all the MIME types defined in the map.
61
     *
62
     * @param string $match (Optional) a match wildcard to limit the list.
63
     *
64
     * @return string[]
65
     */
66 6 View Code Duplication
    public function listTypes($match = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
67
    {
68 6
        $list = array_keys(static::$map['types']);
69
70 6
        if (is_null($match)) {
71 2
            return $list;
72
        } else {
73 4
            $re = strtr($match, ['/' => '\\/', '*' => '.*']);
74
            return array_filter($list, function ($v) use ($re) {
75 4
                return preg_match("/$re/", $v) === 1;
76 4
            });
77
        }
78
    }
79
80
    /**
81
     * Lists all the extensions defined in the map.
82
     *
83
     * @param string $match (Optional) a match wildcard to limit the list.
84
     *
85
     * @return string[]
86
     */
87 2 View Code Duplication
    public function listExtensions($match = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
88
    {
89 2
        $list = array_keys(static::$map['extensions']);
90
91 2
        if (is_null($match)) {
92 2
            return $list;
93
        } else {
94
            $re = strtr($match, ['*' => '.*']);
95
            return array_filter($list, function ($v) use ($re) {
96
                return preg_match("/$re/", $v) === 1;
97
            });
98
        }
99
    }
100
101
    /**
102
     * Determines if an entry exists form the 'types' array.
103
     *
104
     * @param string $type The type to be found.
105
     *
106
     * @return bool
107
     */
108 6
    public function hasType($type)
109
    {
110 6
        return (bool) $this->getType($type);
111
    }
112
113
    /**
114
     * Gets the content of an entry from the 'types' array.
115
     *
116
     * @param string $type The extension to be found.
117
     *
118
     * @return string[] The mapped file extensions.
119
     */
120 6
    public function getType($type)
121
    {
122 6
        $res = $this->getMapEntry('types', $type);
123 6
        return $res ?: [];
124
    }
125
126
    /**
127
     * Determines if an entry exists form the 'extensions' array.
128
     *
129
     * @param string $extension The extension to be found.
130
     *
131
     * @return bool
132
     */
133
    public function hasExtension($extension)
134
    {
135
        return (bool) $this->getExtension($extension);
136
    }
137
138
    /**
139
     * Gets the content of an entry from the 'extensions' array.
140
     *
141
     * @param string $extension The extension to be found.
142
     *
143
     * @return string[] The mapped MIME types.
144
     */
145 9
    public function getExtension($extension)
146
    {
147 9
        $res = $this->getMapEntry('extensions', $extension);
148 9
        return $res ?: [];
149
    }
150
151
    /**
152
     * Gets the content of an entry of the map.
153
     *
154
     * @param string $key
155
     *   The main array key.
156
     * @param string $entry
157
     *   The sub array key.
158
     *
159
     * @return mixed|null
160
     *   The value of the entry, or null if missing.
161
     */
162 13
    protected function getMapEntry($key, $entry)
163
    {
164 13
        return isset(static::$map[$key][$entry]) ? static::$map[$key][$entry] : null;
165
    }
166
167
    /**
168
     * Adds an entry to the map.
169
     *
170
     * Checks that no duplicate entries are made.
171
     *
172
     * @param string $key
173
     *   The main array key.
174
     * @param string $entry
175
     *   The sub array key.
176
     * @param string $value
177
     *   The value to add.
178
     *
179
     * @return $this
180
     */
181 4
    protected function addMapEntry($key, $entry, $value)
182
    {
183 4
        if (!isset(static::$map[$key][$entry])) {
184 4
            static::$map[$key][$entry] = [$value];
185
        } else {
186 3
            if (array_search($value, static::$map[$key][$entry]) === false) {
187 3
                static::$map[$key][$entry][] = $value;
188
            }
189
        }
190 4
        return $this;
191
    }
192
193
    /**
194
     * Removes an entry from the map.
195
     *
196
     * @param string $key
197
     *   The main array key.
198
     * @param string $entry
199
     *   The sub array key.
200
     * @param string $value
201
     *   The value.
202
     *
203
     * @return bool
204
     *   true if the entry was removed, false if the entry was not present.
205
     */
206 1
    protected function removeMapEntry($key, $entry, $value)
207
    {
208
        // Return false if no entry.
209 1
        if (!isset(static::$map[$key][$entry])) {
210 1
            return false;
211
        }
212
213
        // Return false if no value.
214 1
        $k = array_search($value, static::$map[$key][$entry]);
215 1
        if ($k === false) {
216 1
            return false;
217
        }
218
219
        // Remove the map entry.
220 1
        unset(static::$map[$key][$entry][$k]);
221
222
        // Remove the entry itself if no more values.
223 1
        if (empty(static::$map[$key][$entry])) {
224 1
            unset(static::$map[$key][$entry]);
225
        } else {
226
            // Resequence the remaining values.
227 1
            $tmp = [];
228 1
            foreach (static::$map[$key][$entry] as $v) {
229 1
                $tmp[] = $v;
230
            }
231 1
            static::$map[$key][$entry] = $tmp;
232
        }
233
234 1
        return true;
235
    }
236
237
    /**
238
     * Sets a value as the default for an entry.
239
     *
240
     * @param string $key
241
     *   The main array key.
242
     * @param string $entry
243
     *   The sub array key.
244
     * @param string $value
245
     *   The value.
246
     *
247
     * @throws MappingException if no mapping found.
248
     *
249
     * @return $this
250
     */
251 6
    protected function setValueAsDefault($key, $entry, $value)
252
    {
253
        // Throw exception if no entry.
254 6
        if (!isset(static::$map[$key][$entry])) {
255 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry}', '{$entry}' not defined");
256
        }
257
258
        // Throw exception if no entry-value pair.
259 4
        $k = array_search($value, static::$map[$key][$entry]);
260 4
        if ($k === false) {
261 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry}', '{$value}' not associated to '{$entry}'");
262
        }
263
264
        // Move value to top of array and resequence the rest.
265 2
        $tmp = [$value];
266 2
        foreach (static::$map[$key][$entry] as $kk => $v) {
267 2
            if ($kk === $k) {
268 2
                continue;
269
            }
270 2
            $tmp[] = $v;
271
        }
272 2
        static::$map[$key][$entry] = $tmp;
273
274 2
        return $this;
275
    }
276
277
    /**
278
     * Adds a type-to-extension mapping.
279
     *
280
     * @param string $type
281
     *   A MIME type.
282
     * @param string $extension
283
     *   A file extension.
284
     *
285
     * @return $this
286
     */
287 4
    public function addMapping($type, $extension)
288
    {
289 4
        $type = strtolower($type);
290 4
        $extension = (string) strtolower($extension);
291
292
        // Add entry to 'types'.
293 4
        $this->addMapEntry('types', $type, $extension);
294
295
        // Add entry to 'extensions'.
296 4
        $this->addMapEntry('extensions', $extension, $type);
297
298 4
        return $this;
299
    }
300
301
    /**
302
     * Removes a type-to-extension mapping.
303
     *
304
     * @param string $type
305
     *   A MIME type.
306
     * @param string $extension
307
     *   A file extension.
308
     *
309
     * @return bool
310
     *   true if the mapping was removed, false if the mapping was not present.
311
     */
312 1
    public function removeMapping($type, $extension)
313
    {
314 1
        $type = strtolower($type);
315 1
        $extension = (string) strtolower($extension);
316
317
        // Remove entry from 'types'.
318 1
        $type_ret = $this->removeMapEntry('types', $type, $extension);
319
320
        // Remove entry from 'extensions'.
321 1
        $extension_ret = $this->removeMapEntry('extensions', $extension, $type);
322
323 1
        return $type_ret && $extension_ret;
324
    }
325
326
    /**
327
     * Removes the entire mapping of a type.
328
     *
329
     * @param string $type
330
     *   A MIME type.
331
     *
332
     * @return bool
333
     *   true if the mapping was removed, false if the type was not present.
334
     */
335 1
    public function removeType($type)
336
    {
337 1
        $type = strtolower($type);
338
339
        // Return false if type is not found.
340 1
        if (!isset(static::$map['types'][$type])) {
341 1
            return false;
342
        }
343
344
        // Loop through all the associated extensions and remove them. This
345
        // is also removing the type itself when the last extension is removed.
346 1
        foreach (static::$map['types'][$type] as $extension) {
347 1
            $this->removeMapping($type, $extension);
348
        }
349
350 1
        return true;
351
    }
352
353
    /**
354
     * Changes the default extension for a MIME type.
355
     *
356
     * @param string $type
357
     *   A MIME type.
358
     * @param string $extension
359
     *   A file extension.
360
     *
361
     * @throws MappingException if no mapping found.
362
     *
363
     * @return $this
364
     */
365 3
    public function setTypeDefaultExtension($type, $extension)
366
    {
367 3
        $type = strtolower($type);
368 3
        $extension = (string) strtolower($extension);
369
370 3
        return $this->setValueAsDefault('types', $type, $extension);
371
    }
372
373
    /**
374
     * Changes the default MIME type for a file extension.
375
     *
376
     * @param string $extension
377
     *   A file extension.
378
     * @param string $type
379
     *   A MIME type.
380
     *
381
     * @throws MappingException if no mapping found.
382
     *
383
     * @return $this
384
     */
385 3
    public function setExtensionDefaultType($extension, $type)
386
    {
387 3
        $type = strtolower($type);
388 3
        $extension = (string) strtolower($extension);
389
390 3
        return $this->setValueAsDefault('extensions', $extension, $type);
391
    }
392
}
393