Passed
Push — master ( 924112...5ea267 )
by mon
02:22
created

BaseMap::addMapSubEntry()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 4
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 3
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace FileEye\MimeMap\Map;
4
5
use FileEye\MimeMap\MappingException;
6
7
/**
8
 * Abstract base class for managing MimeMap maps.
9
 *
10
 * This class cannot be instantiated; extend from it to implement a map.
11
 */
12
abstract class BaseMap
13
{
14
    /**
15
     * Mapping between file extensions and MIME types.
16
     *
17
     * @var array
18
     */
19
    protected static $map = [];
20
21
    /**
22
     * A backup of the mapping between file extensions and MIME types.
23
     *
24
     * Used during the map update process.
25
     *
26
     * @var array
27
     */
28
    protected static $backupMap;
29
30
    /**
31
     * Backs up the map array.
32
     *
33
     * @return array
34
     */
35 8
    public function backup()
36
    {
37 8
        static::$backupMap = static::$map;
38 8
    }
39
40
    /**
41
     * Resets the map array to the backup.
42
     *
43
     * @return array
44
     */
45 8
    public function reset()
46
    {
47 8
        static::$map = static::$backupMap;
48 8
    }
49
50
    /**
51
     * Returns the singleton.
52
     *
53
     * @return string
54
     */
55 89
    public static function getInstance()
56
    {
57 89
        if (!static::$instance) {
58 3
            static::$instance = new static();
0 ignored issues
show
Bug Best Practice introduced by
The property instance does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
59
        }
60 89
        return static::$instance;
61
    }
62
63
    /**
64
     * Returns this file's full qualified filename.
65
     *
66
     * @return string
67
     */
68 1
    public function getFileName()
69
    {
70 1
        throw new \LogicException(__METHOD__ . ' is not implemented in ' . get_called_class());
71
    }
72
73
    /**
74
     * Gets the map array.
75
     *
76
     * @return array
77
     */
78 5
    public function getMapArray()
79
    {
80 5
        return static::$map;
81
    }
82
83
    /**
84
     * Sorts the map.
85
     *
86
     * @return $this
87
     */
88 7
    public function sort()
89
    {
90 7
        foreach (array_keys(static::$map) as $k) {
91 5
            ksort(static::$map[$k]);
92 5
            foreach (static::$map[$k] as &$sub) {
93 5
                ksort($sub);
94
            }
95
        }
96 7
        return $this;
97
    }
98
99
    /**
100
     * Gets a list of entries of the map.
101
     *
102
     * @param string $entry
103
     *   The main array entry.
104
     * @param string $match
105
     *   (Optional) a match wildcard to limit the list.
106
     *
107
     * @return array
108
     *   The list of the entries.
109
     */
110 7
    protected function listEntries($entry, $match = null)
111
    {
112 7
        $entry = strtolower($entry);
113
114 7
        if (!isset(static::$map[$entry])) {
115 1
            return [];
116
        }
117
118 7
        $list = array_keys(static::$map[$entry]);
119
120 7
        if (is_null($match)) {
121 3
            return $list;
122
        } else {
123 4
            $re = strtr($match, ['/' => '\\/', '*' => '.*']);
124
            return array_filter($list, function ($v) use ($re) {
125 4
                return preg_match("/$re/", $v) === 1;
126 4
            });
127
        }
128
    }
129
130
    /**
131
     * Gets the content of an entry of the map.
132
     *
133
     * @param string $entry
134
     *   The main array entry.
135
     * @param string $entry_key
136
     *   The main entry value.
137
     *
138
     * @return mixed|null
139
     *   The value of the entry, or null if missing.
140
     */
141 36
    protected function getMapEntry($entry, $entry_key)
142
    {
143 36
        $entry = strtolower($entry);
144 36
        $entry_key = strtolower($entry_key);
145 36
        return isset(static::$map[$entry][$entry_key]) ? static::$map[$entry][$entry_key] : null;
146
    }
147
148
    /**
149
     * Gets the content of a subentry of the map.
150
     *
151
     * @param string $entry
152
     *   The main array entry.
153
     * @param string $entry_key
154
     *   The main entry value.
155
     * @param string $sub_entry
156
     *   The sub entry.
157
     *
158
     * @return mixed|null
159
     *   The value of the entry, or null if missing.
160
     */
161 20
    protected function getMapSubEntry($entry, $entry_key, $sub_entry)
162
    {
163 20
        $entry = strtolower($entry);
164 20
        $entry_key = strtolower($entry_key);
165 20
        $sub_entry = strtolower($sub_entry);
166 20
        return isset(static::$map[$entry][$entry_key][$sub_entry]) ? static::$map[$entry][$entry_key][$sub_entry] : null;
167
    }
168
169
    /**
170
     * Adds an entry to the map.
171
     *
172
     * Checks that no duplicate entries are made.
173
     *
174
     * @param string $entry
175
     *   The main array entry.
176
     * @param string $entry_key
177
     *   The main entry value.
178
     * @param string $sub_entry
179
     *   The sub entry.
180
     * @param string $value
181
     *   The value to add.
182
     *
183
     * @return $this
184
     */
185 9
    protected function addMapSubEntry($entry, $entry_key, $sub_entry, $value)
186
    {
187 9
        $entry = strtolower($entry);
188 9
        $entry_key = strtolower($entry_key);
189 9
        $sub_entry = strtolower($sub_entry);
190 9
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
191 9
            static::$map[$entry][$entry_key][$sub_entry] = [$value];
192
        } else {
193 8
            if (array_search($value, static::$map[$entry][$entry_key][$sub_entry]) === false) {
194 8
                static::$map[$entry][$entry_key][$sub_entry][] = $value;
195
            }
196
        }
197 9
        return $this;
198
    }
199
200
    /**
201
     * Removes an entry from the map.
202
     *
203
     * @param string $entry
204
     *   The main array entry.
205
     * @param string $entry_key
206
     *   The main entry value.
207
     * @param string $sub_entry
208
     *   The sub entry.
209
     * @param string $value
210
     *   The value to remove.
211
     *
212
     * @return bool
213
     *   true if the entry was removed, false if the entry was not present.
214
     */
215 4
    protected function removeMapSubEntry($entry, $entry_key, $sub_entry, $value)
216
    {
217 4
        $entry = strtolower($entry);
218 4
        $entry_key = strtolower($entry_key);
219 4
        $sub_entry = strtolower($sub_entry);
220
221
        // Return false if no entry.
222 4
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
223 1
            return false;
224
        }
225
226
        // Return false if no value.
227 4
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
228 4
        if ($k === false) {
229 1
            return false;
230
        }
231
232
        // Remove the map sub entry key.
233 4
        unset(static::$map[$entry][$entry_key][$sub_entry][$k]);
234
235
        // Remove the sub entry if no more values.
236 4
        if (empty(static::$map[$entry][$entry_key][$sub_entry])) {
237 4
            unset(static::$map[$entry][$entry_key][$sub_entry]);
238
        } else {
239
            // Resequence the remaining values.
240 4
            $tmp = [];
241 4
            foreach (static::$map[$entry][$entry_key][$sub_entry] as $v) {
242 4
                $tmp[] = $v;
243
            }
244 4
            static::$map[$entry][$entry_key][$sub_entry] = $tmp;
245
        }
246
247
        // Remove the entry if no more values.
248 4
        if (empty(static::$map[$entry][$entry_key])) {
249 2
            unset(static::$map[$entry][$entry_key]);
250
        }
251
252 4
        return true;
253
    }
254
255
    /**
256
     * Sets a value as the default for an entry.
257
     *
258
     * @param string $entry
259
     *   The main array entry.
260
     * @param string $entry_key
261
     *   The main entry value.
262
     * @param string $sub_entry
263
     *   The sub entry.
264
     * @param string $value
265
     *   The value to add.
266
     *
267
     * @throws MappingException if no mapping found.
268
     *
269
     * @return $this
270
     */
271 9
    protected function setValueAsDefault($entry, $entry_key, $sub_entry, $value)
272
    {
273 9
        $entry = strtolower($entry);
274 9
        $entry_key = strtolower($entry_key);
275 9
        $sub_entry = strtolower($sub_entry);
276
277
        // Throw exception if no entry.
278 9
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
279 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$entry_key}' not defined");
280
        }
281
282
        // Throw exception if no entry-value pair.
283 7
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
284 7
        if ($k === false) {
285 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$value}' not associated to '{$entry_key}'");
286
        }
287
288
        // Move value to top of array and resequence the rest.
289 5
        $tmp = [$value];
290 5
        foreach (static::$map[$entry][$entry_key][$sub_entry] as $kk => $v) {
291 5
            if ($kk === $k) {
292 5
                continue;
293
            }
294 5
            $tmp[] = $v;
295
        }
296 5
        static::$map[$entry][$entry_key][$sub_entry] = $tmp;
297
298 5
        return $this;
299
    }
300
}
301