Passed
Push — master ( 4ceb11...107b40 )
by mon
01:56
created

BaseMap::listEntries()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

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