Passed
Pull Request — master (#7)
by mon
04:04
created

MapUpdater   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 88.1%

Importance

Changes 0
Metric Value
wmc 11
lcom 0
cbo 4
dl 0
loc 130
ccs 37
cts 42
cp 0.881
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A createMapFromSourceFile() 0 21 5
A compareMaps() 0 23 3
A applyOverrides() 0 6 2
A writeMapToCodeFile() 0 9 1
1
<?php
2
3
namespace FileEye\MimeMap;
4
5
use SebastianBergmann\Comparator\ComparisonFailure;
6
use SebastianBergmann\Comparator\Factory;
7
use SebastianBergmann\Diff\Differ;
8
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
9
10
/**
11
 * Compiles the MIME type to file extension map.
12
 */
13
class MapUpdater
14
{
15
    /**
16
     * Default URL where to read the specification from.
17
     *
18
     * The apache httpd project contains the most complete list of file
19
     * extension to mime type mapping on the planet. We use it to update our
20
     * own list.
21
     */
22
    const DEFAULT_SOURCE_FILE = 'http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co';
23
24
    /**
25
     * 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
    const DEFAULT_OVERRIDE_FILE = __DIR__ . '/../resources/overrides.yml';
32
33
    /**
34
     * Creates a new type-to-extension map reading from a file.
35
     *
36
     * @param string $source_file
37
     *   (Optional) the source file. Defaults to the Apache source bind_textdomain_codeset
38
     *   repository file where MIME types and file extensions are associated.
39
     *
40
     * @throws \RuntimeException if file I/O error occurs.
41
     *
42
     * @return MapHandler
43
     *   The map handler with the new map.
44
     */
45 5
    public function createMapFromSourceFile($source_file = MapUpdater::DEFAULT_SOURCE_FILE)
46
    {
47 5
        $map = new MapHandler([]);
48 5
        $lines = file($source_file);
49 5
        foreach ($lines as $line) {
50 4
            if ($line{0} == '#') {
51 4
                continue;
52
            }
53 4
            $line = preg_replace("#\\s+#", ' ', trim($line));
54 4
            $parts = explode(' ', $line);
55 4
            $type = array_shift($parts);
56 4
            foreach ($parts as $extension) {
57 4
                $map->addMapping($type, $extension);
58
            }
59
        }
60 5
        $map_array = $map->get();
61 5
        if (empty($map_array)) {
62 1
            throw new \RuntimeException('No data found in file ' . $source_file);
63
        }
64 4
        return $map;
65
    }
66
67
    /**
68
     * Compares two type-to-extension maps by section.
69
     *
70
     * @param MapHandler $old_map
71
     *   The first map to compare.
72
     * @param MapHandler $new_map
73
     *   The second map to compare.
74
     * @param string $section
75
     *   The first-level array key to compare: 'types' or 'extensions'.
76
     *
77
     * @throws \RuntimeException with diff details if the maps differ.
78
     *
79
     * @return bool
80
     *   True if the maps are equal.
81
     */
82 2
    public function compareMaps(MapHandler $old_map, MapHandler $new_map, $section)
83
    {
84 2
        $old_map->sort();
85 2
        $new_map->sort();
86 2
        $old = $old_map->get();
87 2
        $new = $new_map->get();
88
89 2
        $factory = new Factory;
90 2
        $comparator = $factory->getComparatorFor($old[$section], $new[$section]);
91
        try {
92 2
            $comparator->assertEquals($old[$section], $new[$section]);
93 1
            return true;
94 1
        } catch (ComparisonFailure $failure) {
95 1
            $old_string = var_export($old[$section], true);
96 1
            $new_string = var_export($new[$section], true);
97 1
            if (PHP_VERSION_ID >= 70000) {
98 1
                $differ = new Differ(new UnifiedDiffOutputBuilder("--- Removed\n+++ Added\n"));
99 1
                throw new \RuntimeException($differ->diff($old_string, $new_string));
100
            } else {
101
                throw new \RuntimeException(' ');
102
            }
103
        }
104
    }
105
106
    /**
107
     * Applies to the map an array of overrides.
108
     *
109
     * @param MapHandler $map
110
     *   The map.
111
     * @param array $overrides
112
     *   The overrides to be applied.
113
     *
114
     * @return void
115
     */
116
    public function applyOverrides(MapHandler $map, array $overrides)
117
    {
118
        foreach ($overrides as $command) {
119
            call_user_func_array([$map, $command[0]], $command[1]);
120
        }
121
    }
122
123
    /**
124
     * Updates the map at a destination PHP file.
125
     *
126
     * @param MapHandler $map
127
     *   The map.
128
     * @param string $output_file
129
     *   The destination PHP file.
130
     *
131
     * @return void
132
     */
133 1
    public function writeMapToCodeFile(MapHandler $map, $output_file)
134
    {
135 1
        $content = preg_replace(
136 1
            '#public static \$map = (.+?);#s',
137 1
            "public static \$map = " . var_export($map->get(), true) . ";",
138 1
            file_get_contents($output_file)
139
        );
140 1
        file_put_contents($output_file, $content);
141 1
    }
142
}
143