BaseMap::getFileName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
crap 1
1
<?php declare(strict_types=1);
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<int|string, array<string, array<int,string>>>>
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<int|string, array<string, array<int,string>>>>|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 8
    public function reset(): void
47
    {
48 8
        if (isset(static::$backupMap)) {
49 8
            static::$map = static::$backupMap;
50
        }
51 8
        static::$backupMap = null;
52
    }
53
54 105
    public static function getInstance(): MapInterface
55
    {
56 105
        if (static::$instance === null) {
57 3
            static::$instance = new static();
58
        }
59 105
        return static::$instance;
60
    }
61
62 1
    public function getFileName(): string
63
    {
64 1
        throw new \LogicException(__METHOD__ . ' is not implemented in ' . get_called_class());
65
    }
66
67 5
    public function getMapArray(): array
68
    {
69 5
        return static::$map;
70
    }
71
72 7
    public function sort(): MapInterface
73
    {
74 7
        foreach (array_keys(static::$map) as $k) {
75 5
            ksort(static::$map[$k]);
76 5
            foreach (static::$map[$k] as &$sub) {
77 5
                ksort($sub);
78
            }
79
        }
80 7
        return $this;
81
    }
82
83
    /**
84
     * Gets a list of entries of the map.
85
     *
86
     * @param string $entry
87
     *   The main array entry.
88
     * @param string $match
89
     *   (Optional) a match wildcard to limit the list.
90
     *
91
     * @return array<int, int|string>
92
     *   The list of the entries.
93
     */
94 7
    protected function listEntries(string $entry, string $match = null): array
95
    {
96 7
        if (!isset(static::$map[$entry])) {
97 1
            return [];
98
        }
99
100 7
        $list = array_keys(static::$map[$entry]);
101
102 7
        if (is_null($match)) {
103 3
            return $list;
104
        } else {
105 4
            $re = strtr($match, ['/' => '\\/', '*' => '.*']);
106 4
            return array_filter($list, function ($v) use ($re) {
107 4
                return preg_match("/$re/", (string) $v) === 1;
108
            });
109
        }
110
    }
111
112
    /**
113
     * Gets the content of an entry of the map.
114
     *
115
     * @param string $entry
116
     *   The main array entry.
117
     * @param string $entry_key
118
     *   The main entry value.
119
     *
120
     * @return array<string|int,array<string>>
121
     *   The values of the entry, or empty array if missing.
122
     */
123 49
    protected function getMapEntry(string $entry, string $entry_key): array
124
    {
125 49
        return isset(static::$map[$entry][$entry_key]) ? static::$map[$entry][$entry_key] : [];
126
    }
127
128
    /**
129
     * Gets the content of a subentry of the map.
130
     *
131
     * @param string $entry
132
     *   The main array entry.
133
     * @param string $entry_key
134
     *   The main entry value.
135
     * @param string $sub_entry
136
     *   The sub entry.
137
     *
138
     * @return string[]
139
     *   The values of the subentry, or empty array if missing.
140
     */
141 31
    protected function getMapSubEntry(string $entry, string $entry_key, string $sub_entry): array
142
    {
143 31
        return isset(static::$map[$entry][$entry_key][$sub_entry]) ? static::$map[$entry][$entry_key][$sub_entry] : [];
144
    }
145
146
    /**
147
     * Adds an entry to the map.
148
     *
149
     * Checks that no duplicate entries are made.
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
     * @param string $value
158
     *   The value to add.
159
     *
160
     * @return $this
161
     */
162 9
    protected function addMapSubEntry(string $entry, string $entry_key, string $sub_entry, string $value): MapInterface
163
    {
164 9
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
165 9
            static::$map[$entry][$entry_key][$sub_entry] = [$value];
166
        } else {
167 8
            if (array_search($value, static::$map[$entry][$entry_key][$sub_entry]) === false) {
168 8
                static::$map[$entry][$entry_key][$sub_entry][] = $value;
169
            }
170
        }
171 9
        return $this;
172
    }
173
174
    /**
175
     * Removes an entry from the map.
176
     *
177
     * @param string $entry
178
     *   The main array entry.
179
     * @param string $entry_key
180
     *   The main entry value.
181
     * @param string $sub_entry
182
     *   The sub entry.
183
     * @param string $value
184
     *   The value to remove.
185
     *
186
     * @return bool
187
     *   true if the entry was removed, false if the entry was not present.
188
     */
189 13
    protected function removeMapSubEntry(string $entry, string $entry_key, string $sub_entry, string $value): bool
190
    {
191
        // Return false if no entry.
192 13
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
193 1
            return false;
194
        }
195
196
        // Return false if no value.
197 13
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
198 13
        if ($k === false) {
199 1
            return false;
200
        }
201
202
        // Remove the map sub entry key.
203 13
        unset(static::$map[$entry][$entry_key][$sub_entry][$k]);
204
205
        // Remove the sub entry if no more values.
206 13
        if (empty(static::$map[$entry][$entry_key][$sub_entry])) {
207 13
            unset(static::$map[$entry][$entry_key][$sub_entry]);
208
        } else {
209
            // Resequence the remaining values.
210 13
            $tmp = [];
211 13
            foreach (static::$map[$entry][$entry_key][$sub_entry] as $v) {
212 13
                $tmp[] = $v;
213
            }
214 13
            static::$map[$entry][$entry_key][$sub_entry] = $tmp;
215
        }
216
217
        // Remove the entry if no more values.
218 13
        if (empty(static::$map[$entry][$entry_key])) {
219 11
            unset(static::$map[$entry][$entry_key]);
220
        }
221
222 13
        return true;
223
    }
224
225
    /**
226
     * Sets a value as the default for an entry.
227
     *
228
     * @param string $entry
229
     *   The main array entry.
230
     * @param string $entry_key
231
     *   The main entry value.
232
     * @param string $sub_entry
233
     *   The sub entry.
234
     * @param string $value
235
     *   The value to add.
236
     *
237
     * @throws MappingException if no mapping found.
238
     *
239
     * @return $this
240
     */
241 9
    protected function setValueAsDefault(string $entry, string $entry_key, string $sub_entry, string $value): MapInterface
242
    {
243
        // Throw exception if no entry.
244 9
        if (!isset(static::$map[$entry][$entry_key][$sub_entry])) {
245 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$entry_key}' not defined");
246
        }
247
248
        // Throw exception if no entry-value pair.
249 7
        $k = array_search($value, static::$map[$entry][$entry_key][$sub_entry]);
250 7
        if ($k === false) {
251 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry_key}', '{$value}' not associated to '{$entry_key}'");
252
        }
253
254
        // Move value to top of array and resequence the rest.
255 5
        $tmp = [$value];
256 5
        foreach (static::$map[$entry][$entry_key][$sub_entry] as $kk => $v) {
257 5
            if ($kk === $k) {
258 5
                continue;
259
            }
260 5
            $tmp[] = $v;
261
        }
262 5
        static::$map[$entry][$entry_key][$sub_entry] = $tmp;
263
264 5
        return $this;
265
    }
266
}
267