Passed
Push — master ( 924112...5ea267 )
by mon
02:22
created

MapUpdater::loadMapFromFreedesktopFile()   D

Complexity

Conditions 14
Paths 304

Size

Total Lines 59
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 14

Importance

Changes 0
Metric Value
cc 14
eloc 32
nc 304
nop 1
dl 0
loc 59
rs 4.1333
c 0
b 0
f 0
ccs 32
cts 32
cp 1
crap 14

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace FileEye\MimeMap;
4
5
use FileEye\MimeMap\Map\AbstractMap;
6
7
/**
8
 * Compiles the MIME type to file extension map.
9
 */
10
class MapUpdater
11
{
12
    /**
13
     * The default, empty, base map to use for update.
14
     */
15
    const DEFAULT_BASE_MAP_CLASS = '\FileEye\MimeMap\Map\EmptyMap';
16
17
    /**
18
     * The AbstractMap object to update.
19
     *
20
     * @var AbstractMap
21
     */
22
    protected $map;
23
24
    /**
25
     * Returns the default file with override commands to be executed.
26
     *
27
     * The YAML file provides an array of calls to MapHandler methods to be
28
     * executed sequentially. Each entry indicates the method to be invoked and
29
     * the arguments to be passed in.
30
     *
31
     * @return string
32
     */
33 1
    public static function getDefaultMapBuildFile()
34
    {
35 1
        return __DIR__ . '/../resources/default_map_build.yml';
36
    }
37
38
    /**
39
     * Returns the AbstractMap object being updated.
40
     *
41
     * @return AbstractMap
42
     */
43 8
    public function getMap()
44
    {
45 8
        return $this->map;
46
    }
47
48
    /**
49
     * Sets the AbstractMap object to update.
50
     *
51
     * @param string $map_class
52
     *   The FQCN of the map to be updated.
53
     *
54
     * @return $this
55
     */
56 8
    public function selectBaseMap($map_class)
57
    {
58 8
        $this->map = MapHandler::map($map_class);
59 8
        $this->map->backup();
60 8
        return $this;
61
    }
62
63
    /**
64
     * Loads a new type-to-extension map reading from a file in Apache format.
65
     *
66
     * @param string $source_file
67
     *   The source file. The file must conform to the format in the Apache
68
     *   source code repository file where MIME types and file extensions are
69
     *   associated.
70
     *
71
     * @return string[]
72
     *   An array of error messages.
73
     */
74 3
    public function loadMapFromApacheFile($source_file)
75
    {
76 3
        $errors = [];
77
78 3
        $lines = file($source_file);
79 3
        foreach ($lines as $line) {
80 2
            if ($line{0} == '#') {
81 2
                continue;
82
            }
83 2
            $line = preg_replace("#\\s+#", ' ', trim($line));
84 2
            $parts = explode(' ', $line);
85 2
            $type = array_shift($parts);
86 2
            foreach ($parts as $extension) {
87 2
                $this->map->addTypeExtensionMapping($type, $extension);
88
            }
89
        }
90 3
        $this->map->sort();
91
92 3
        return $errors;
93
    }
94
95
    /**
96
     * Loads a new type-to-extension map reading from a Freedesktop.org file.
97
     *
98
     * @param string $source_file
99
     *   The source file. The file must conform to the format in the
100
     *   Freedesktop.org database.
101
     *
102
     * @return string[]
103
     *   An array of error messages.
104
     */
105 3
    public function loadMapFromFreedesktopFile($source_file)
106
    {
107 3
        $errors = [];
108 3
        $xml = simplexml_load_string(file_get_contents($source_file));
109 3
        $aliases = [];
110
111 3
        foreach ($xml as $node) {
112 2
            $exts = [];
113 2
            foreach ($node->glob as $glob) {
114 2
                $pattern = (string) $glob['pattern'];
115 2
                if ('*' != $pattern[0] || '.' != $pattern[1]) {
116 2
                    continue;
117
                }
118 2
                $exts[] = substr($pattern, 2);
119
            }
120 2
            if (empty($exts)) {
121 2
                continue;
122
            }
123
124 2
            $type = (string) $node['type'];
125
126
            // Add description.
127 2
            if (isset($node->comment)) {
128 2
                $this->map->addTypeDescription($type, (string) $node->comment[0]);
129
            }
130 2
            if (isset($node->acronym)) {
131 2
                $acronym = (string) $node->acronym;
132 2
                if (isset($node->{'expanded-acronym'})) {
133 2
                    $acronym .= ': ' . (string) $node->{'expanded-acronym'};
134
                }
135 2
                $this->map->addTypeDescription($type, $acronym);
136
            }
137
138
            // Add extensions.
139 2
            foreach ($exts as $ext) {
140 2
                $this->map->addTypeExtensionMapping($type, $ext);
141
            }
142
143
            // All aliases are accumulated and processed at the end of the
144
            // cycle to allow proper consistency checking on the completely
145
            // developed list of types.
146 2
            foreach ($node->alias as $alias) {
147 2
                $aliases[$type][] = (string) $alias['type'];
148
            }
149
        }
150
151
        // Add all the aliases, provide logging of errors.
152 3
        foreach ($aliases as $type => $a) {
153 2
            foreach ($a as $alias) {
154
                try {
155 2
                    $this->map->addTypeAlias($type, $alias);
156 1
                } catch (MappingException $e) {
157 2
                    $errors[] = $e->getMessage();
158
                }
159
            }
160
        }
161 3
        $this->map->sort();
162
163 3
        return $errors;
164
    }
165
166
    /**
167
     * Applies to the map an array of overrides.
168
     *
169
     * @param array $overrides
170
     *   The overrides to be applied.
171
     *
172
     * @return string[]
173
     *   An array of error messages.
174
     */
175 3
    public function applyOverrides(array $overrides)
176
    {
177 3
        $errors = [];
178
179 3
        foreach ($overrides as $command) {
180
            try {
181 3
                call_user_func_array([$this->map, $command[0]], $command[1]);
182 1
            } catch (MappingException $e) {
183 3
                $errors[] = $e->getMessage();
184
            }
185
        }
186 3
        $this->map->sort();
187
188 3
        return $errors;
189
    }
190
191
    /**
192
     * Updates the map at a destination PHP file.
193
     *
194
     * @return $this
195
     */
196 1
    public function writeMapToPhpClassFile($file)
197
    {
198 1
        $content = preg_replace(
199 1
            '#protected static \$map = (.+?);#s',
200 1
            "protected static \$map = " . var_export($this->map->getMapArray(), true) . ";",
201 1
            file_get_contents($file)
202
        );
203 1
        file_put_contents($file, $content);
204 1
        return $this;
205
    }
206
}
207