Passed
Pull Request — master (#4)
by mon
01:40
created

MapHandler::setValueAsDefault()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 13
cts 13
cp 1
rs 9.2088
c 0
b 0
f 0
cc 5
nc 5
nop 3
crap 5
1
<?php
2
3
namespace FileEye\MimeMap;
4
5
/**
6
 * Class for managing the type-to-extension map.
7
 */
8
class MapHandler
9
{
10
    /**
11
     * Mapping between file extensions and MIME types.
12
     *
13
     * The array has two main keys, 'types' that maps MIME types to file
14
     * extensions, and 'extensions' that map file extensions to MIME types.
15
     *
16
     * @var array
17
     */
18
    protected $map;
19
20
    /**
21
     * Constructor.
22
     *
23
     * @param array $map
24
     *   (Optional) The mapping to be used for this instance. If null, the
25
     *   default map will be used.
26
     */
27 17
    public function __construct(array $map = null)
28
    {
29 17
        if (is_null($map)) {
30 17
            $this->map = &TypeExtensionMap::$map;
31
        } else {
32
            $this->map = $map;
33
        }
34 17
    }
35
36
    /**
37
     * Returns the map associated with this instance.
38
     *
39
     * @return array
40
     */
41 13
    public function get()
42
    {
43 13
        return $this->map;
44
    }
45
46
    /**
47
     * Sorts the map.
48
     *
49
     * @return $this
50
     */
51 1
    public function sort()
52
    {
53 1
        ksort($this->map['types']);
54 1
        ksort($this->map['extensions']);
55 1
        return $this;
56
    }
57
58
    /**
59
     * Adds an entry to the map.
60
     *
61
     * Checks that no duplicate entries are made.
62
     *
63
     * @param string $key
64
     *   The main array key.
65
     * @param string $entry
66
     *   The sub array key.
67
     * @param string $value
68
     *   The value to add.
69
     *
70
     * @return $this
71
     */
72 2
    protected function addMapEntry($key, $entry, $value)
73
    {
74 2
        if (!isset($this->map[$key][$entry])) {
75 2
            $this->map[$key][$entry] = [$value];
76
        } else {
77 1
            if (array_search($value, $this->map[$key][$entry]) === false) {
78 1
                $this->map[$key][$entry][] = $value;
79
            }
80
        }
81 2
        return $this;
82
    }
83
84
    /**
85
     * Removes an entry from the map.
86
     *
87
     * @param string $key
88
     *   The main array key.
89
     * @param string $entry
90
     *   The sub array key.
91
     * @param string $value
92
     *   The value.
93
     *
94
     * @return bool
95
     *   true if the entry was removed, false if the entry was not present.
96
     */
97 1
    protected function removeMapEntry($key, $entry, $value)
98
    {
99
        // Return false if no entry.
100 1
        if (!isset($this->map[$key][$entry])) {
101 1
            return false;
102
        }
103
104
        // Return false if no value.
105 1
        $k = array_search($value, $this->map[$key][$entry]);
106 1
        if ($k === false) {
107 1
            return false;
108
        }
109
110
        // Remove the map entry.
111 1
        unset($this->map[$key][$entry][$k]);
112
113
        // Remove the entry itself if no more values.
114 1
        if (empty($this->map[$key][$entry])) {
115 1
            unset($this->map[$key][$entry]);
116
        } else {
117
            // Resequence the remaining values.
118 1
            $tmp = [];
119 1
            foreach ($this->map[$key][$entry] as $v) {
120 1
                $tmp[] = $v;
121
            }
122 1
            $this->map[$key][$entry] = $tmp;
123
        }
124
125 1
        return true;
126
    }
127
128
    /**
129
     * Sets a value as the default for an entry.
130
     *
131
     * @param string $key
132
     *   The main array key.
133
     * @param string $entry
134
     *   The sub array key.
135
     * @param string $value
136
     *   The value.
137
     *
138
     * @throws MappingException if no mapping found.
139
     *
140
     * @return $this
141
     */
142 6
    protected function setValueAsDefault($key, $entry, $value)
143
    {
144
        // Throw exception if no entry.
145 6
        if (!isset($this->map[$key][$entry])) {
146 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry}', '{$entry}' not defined");
147
        }
148
149
        // Throw exception if no entry-value pair.
150 4
        $k = array_search($value, $this->map[$key][$entry]);
151 4
        if ($k === false) {
152 2
            throw new MappingException("Cannot set '{$value}' as default for '{$entry}', '{$value}' not associated to '{$entry}'");
153
        }
154
155
        // Move value to top of array and resequence the rest.
156 2
        $tmp = [$value];
157 2
        foreach ($this->map[$key][$entry] as $kk => $v) {
158 2
            if ($kk === $k) {
159 2
                continue;
160
            }
161 2
            $tmp[] = $v;
162
        }
163 2
        $this->map[$key][$entry] = $tmp;
164
165 2
        return $this;
166
    }
167
168
    /**
169
     * Adds a type-to-extension mapping.
170
     *
171
     * @param string $type
172
     *   A MIME type.
173
     * @param string $extension
174
     *   A file extension.
175
     *
176
     * @return $this
177
     */
178 2
    public function addMapping($type, $extension)
179
    {
180 2
        $type = strtolower($type);
181 2
        $extension = (string) strtolower($extension);
182
183
        // Add entry to 'types'.
184 2
        $this->addMapEntry('types', $type, $extension);
185
186
        // Add entry to 'extensions'.
187 2
        $this->addMapEntry('extensions', $extension, $type);
188
189 2
        return $this;
190
    }
191
192
    /**
193
     * Removes a type-to-extension mapping.
194
     *
195
     * @param string $type
196
     *   A MIME type.
197
     * @param string $extension
198
     *   A file extension.
199
     *
200
     * @return bool
201
     *   true if the mapping was removed, false if the mapping was not present.
202
     */
203 1
    public function removeMapping($type, $extension)
204
    {
205 1
        $type = strtolower($type);
206 1
        $extension = (string) strtolower($extension);
207
208
        // Remove entry from 'types'.
209 1
        $type_ret = $this->removeMapEntry('types', $type, $extension);
210
211
        // Remove entry from 'extensions'.
212 1
        $extension_ret = $this->removeMapEntry('extensions', $extension, $type);
213
214 1
        return $type_ret && $extension_ret;
215
    }
216
217
    /**
218
     * Removes the entire mapping of a type.
219
     *
220
     * @param string $type
221
     *   A MIME type.
222
     *
223
     * @return bool
224
     *   true if the mapping was removed, false if the type was not present.
225
     */
226 1
    public function removeType($type)
227
    {
228 1
        $type = strtolower($type);
229
230
        // Return false if type is not found.
231 1
        if (!isset($this->map['types'][$type])) {
232 1
            return false;
233
        }
234
235
        // Loop through all the associated extensions and remove them. This
236
        // is also removing the type itself when the last extension is removed.
237 1
        foreach ($this->map['types'][$type] as $extension) {
238 1
            $this->removeMapping($type, $extension);
239
        }
240
241 1
        return true;
242
    }
243
244
    /**
245
     * Changes the default extension for a MIME type.
246
     *
247
     * @param string $type
248
     *   A MIME type.
249
     * @param string $extension
250
     *   A file extension.
251
     *
252
     * @throws MappingException if no mapping found.
253
     *
254
     * @return $this
255
     */
256 3
    public function setTypeDefaultExtension($type, $extension)
257
    {
258 3
        $type = strtolower($type);
259 3
        $extension = (string) strtolower($extension);
260
261 3
        return $this->setValueAsDefault('types', $type, $extension);
262
    }
263
264
    /**
265
     * Changes the default MIME type for a file extension.
266
     *
267
     * @param string $extension
268
     *   A file extension.
269
     * @param string $type
270
     *   A MIME type.
271
     *
272
     * @throws MappingException if no mapping found.
273
     *
274
     * @return $this
275
     */
276 3
    public function setExtensionDefaultType($extension, $type)
277
    {
278 3
        $type = strtolower($type);
279 3
        $extension = (string) strtolower($extension);
280
281 3
        return $this->setValueAsDefault('extensions', $extension, $type);
282
    }
283
}
284