Test Failed
Pull Request — master (#58)
by mon
01:58
created

BaseMap   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 256
Duplicated Lines 0 %

Test Coverage

Coverage 88.06%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 62
c 2
b 0
f 0
dl 0
loc 256
ccs 59
cts 67
cp 0.8806
rs 9.92
wmc 31

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A sort() 0 9 3
A backup() 0 3 1
A getMapSubEntry() 0 3 2
A addMapSubEntry() 0 10 3
A getInstance() 0 6 2
A setValueAsDefault() 0 24 5
A getMapEntry() 0 3 2
A removeMapSubEntry() 0 34 6
A getFileName() 0 3 1
A getMapArray() 0 3 1
A listEntries() 0 14 3
A reset() 0 4 1
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.
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<string,array<string,array<string,list>>>
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<string,array<string,array<string,list>>>|null
34
     */
35
    protected static $backupMap;
36
37
    public function __construct()
38
    {
39
    }
40
41 8
    public function backup(): void
42
    {
43 8
        static::$backupMap = static::$map;
44
    }
45
46
    public function reset(): void
47
    {
48
        static::$map = static::$backupMap;
49
        static::$backupMap = null;
50
    }
51
52
    /**
53
     * Returns the singleton.
54
     *
55
     * @return static
56
     */
57 95
    public static function getInstance(): MapInterface
58
    {
59 95
        if (static::$instance === null) {
60 2
            static::$instance = new static();
61
        }
62 95
        return static::$instance;
63
    }
64
65
    public function getFileName(): string
66
    {
67
        throw new \LogicException(__METHOD__ . ' is not implemented in ' . get_called_class());
68
    }
69
70
    public function getMapArray(): array
71
    {
72
        return static::$map;
73
    }
74
75 1
    public function sort(): MapInterface
76
    {
77 1
        foreach (array_keys(static::$map) as $k) {
78 1
            ksort(static::$map[$k]);
79 1
            foreach (static::$map[$k] as &$sub) {
80 1
                ksort($sub);
81
            }
82
        }
83 1
        return $this;
84
    }
85
86
    /**
87
     * Gets a list of entries of the map.
88
     *
89
     * @param string $entry
90
     *   The main array entry.
91
     * @param string $match
92
     *   (Optional) a match wildcard to limit the list.
93
     *
94
     * @return array
95
     *   The list of the entries.
96
     */
97 5
    protected function listEntries(string $entry, string $match = null): array
98
    {
99 5
        if (!isset(static::$map[$entry])) {
100
            return [];
101
        }
102
103 5
        $list = array_keys(static::$map[$entry]);
104
105 5
        if (is_null($match)) {
106 1
            return $list;
107
        } else {
108 4
            $re = strtr($match, ['/' => '\\/', '*' => '.*']);
109 4
            return array_filter($list, function ($v) use ($re) {
110 4
                return preg_match("/$re/", $v) === 1;
111
            });
112
        }
113
    }
114
115
    /**
116
     * Gets the content of an entry of the map.
117
     *
118
     * @param string $entry
119
     *   The main array entry.
120
     * @param string $entry_key
121
     *   The main entry value.
122
     *
123
     * @return mixed|null
124
     *   The value of the entry, or null if missing.
125
     */
126 32
    protected function getMapEntry(string $entry, string $entry_key)
127
    {
128 32
        return isset(static::$map[$entry][$entry_key]) ? static::$map[$entry][$entry_key] : null;
129
    }
130
131
    /**
132
     * Gets the content of a subentry of the map.
133
     *
134
     * @param string $entry
135
     *   The main array entry.
136
     * @param string $entry_key
137
     *   The main entry value.
138
     * @param string $sub_entry
139
     *   The sub entry.
140
     *
141
     * @return mixed|null
142
     *   The value of the entry, or null if missing.
143
     */
144 20
    protected function getMapSubEntry(string $entry, string $entry_key, string $sub_entry)
145
    {
146 20
        return isset(static::$map[$entry][$entry_key][$sub_entry]) ? static::$map[$entry][$entry_key][$sub_entry] : null;
147
    }
148
149
    /**
150
     * Adds an entry to the map.
151
     *
152
     * Checks that no duplicate entries are made.
153
     *
154
     * @param string $entry
155
     *   The main array entry.
156
     * @param string $entry_key
157
     *   The main entry value.
158
     * @param string $sub_entry
159
     *   The sub entry.
160
     * @param string $value
161
     *   The value to add.
162
     *
163
     * @return $this
164
     */
165 5
    protected function addMapSubEntry(string $entry, string $entry_key, string $sub_entry, string $value): MapInterface
166
    {
167 5
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
168 5
            static::$map[$entry][$entry_key][$sub_entry] = [$value];
169
        } else {
170 4
            if (array_search($value, static::$map[$entry][$entry_key][$sub_entry]) === false) {
0 ignored issues
show
Bug introduced by
static::map[$entry][$entry_key][$sub_entry] of type FileEye\MimeMap\Map\list is incompatible with the type array expected by parameter $haystack of array_search(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
            if (array_search($value, /** @scrutinizer ignore-type */ static::$map[$entry][$entry_key][$sub_entry]) === false) {
Loading history...
171 4
                static::$map[$entry][$entry_key][$sub_entry][] = $value;
172
            }
173
        }
174 5
        return $this;
175
    }
176
177
    /**
178
     * Removes an entry from the map.
179
     *
180
     * @param string $entry
181
     *   The main array entry.
182
     * @param string $entry_key
183
     *   The main entry value.
184
     * @param string $sub_entry
185
     *   The sub entry.
186
     * @param string $value
187
     *   The value to remove.
188
     *
189
     * @return bool
190
     *   true if the entry was removed, false if the entry was not present.
191
     */
192 4
    protected function removeMapSubEntry(string $entry, string $entry_key, string $sub_entry, string $value): bool
193
    {
194
        // Return false if no entry.
195 4
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
196 1
            return false;
197
        }
198
199
        // Return false if no value.
200 4
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
0 ignored issues
show
Bug introduced by
static::map[$entry][$entry_key][$sub_entry] of type FileEye\MimeMap\Map\list is incompatible with the type array expected by parameter $haystack of array_search(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

200
        $k = array_search($value, /** @scrutinizer ignore-type */ static::$map[$entry][$entry_key][$sub_entry]);
Loading history...
201 4
        if ($k === false) {
202 1
            return false;
203
        }
204
205
        // Remove the map sub entry key.
206 4
        unset(static::$map[$entry][$entry_key][$sub_entry][$k]);
207
208
        // Remove the sub entry if no more values.
209 4
        if (empty(static::$map[$entry][$entry_key][$sub_entry])) {
210 4
            unset(static::$map[$entry][$entry_key][$sub_entry]);
211
        } else {
212
            // Resequence the remaining values.
213 4
            $tmp = [];
214 4
            foreach (static::$map[$entry][$entry_key][$sub_entry] as $v) {
215 4
                $tmp[] = $v;
216
            }
217 4
            static::$map[$entry][$entry_key][$sub_entry] = $tmp;
218
        }
219
220
        // Remove the entry if no more values.
221 4
        if (empty(static::$map[$entry][$entry_key])) {
222 2
            unset(static::$map[$entry][$entry_key]);
223
        }
224
225 4
        return true;
226
    }
227
228
    /**
229
     * Sets a value as the default for an entry.
230
     *
231
     * @param string $entry
232
     *   The main array entry.
233
     * @param string $entry_key
234
     *   The main entry value.
235
     * @param string $sub_entry
236
     *   The sub entry.
237
     * @param string $value
238
     *   The value to add.
239
     *
240
     * @throws MappingException if no mapping found.
241
     *
242
     * @return $this
243
     */
244 9
    protected function setValueAsDefault(string $entry, string $entry_key, string $sub_entry, string $value): MapInterface
245
    {
246
        // Throw exception if no entry.
247 9
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
248 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$entry_key}' not defined");
249
        }
250
251
        // Throw exception if no entry-value pair.
252 7
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
0 ignored issues
show
Bug introduced by
static::map[$entry][$entry_key][$sub_entry] of type FileEye\MimeMap\Map\list is incompatible with the type array expected by parameter $haystack of array_search(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

252
        $k = array_search($value, /** @scrutinizer ignore-type */ static::$map[$entry][$entry_key][$sub_entry]);
Loading history...
253 7
        if ($k === false) {
254 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$value}' not associated to '{$entry_key}'");
255
        }
256
257
        // Move value to top of array and resequence the rest.
258 5
        $tmp = [$value];
259 5
        foreach (static::$map[$entry][$entry_key][$sub_entry] as $kk => $v) {
260 5
            if ($kk === $k) {
261 5
                continue;
262
            }
263 5
            $tmp[] = $v;
264
        }
265 5
        static::$map[$entry][$entry_key][$sub_entry] = $tmp;
266
267 5
        return $this;
268
    }
269
}
270