Completed
Pull Request — master (#26)
by mon
02:31
created

BaseMap::getInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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