Passed
Pull Request — master (#9)
by mon
02:42
created

UpdateCommand::compareMaps()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
cc 3
nc 3
nop 3
1
<?php
2
3
namespace FileEye\MimeMap\Command;
4
5
use SebastianBergmann\Comparator\ComparisonFailure;
6
use SebastianBergmann\Comparator\Factory;
7
use SebastianBergmann\Diff\Differ;
8
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Yaml\Yaml;
14
use FileEye\MimeMap\Map\AbstractMap;
15
use FileEye\MimeMap\MapHandler;
16
use FileEye\MimeMap\MapUpdater;
17
18
/**
19
 * A Symfony application command to update the MIME type to extension map.
20
 */
21
class UpdateCommand extends Command
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    protected function configure()
27
    {
28
        $this
29
            ->setName('update')
30
            ->setDescription('Updates the MIME-type-to-extension map. Reads the source file specified by --source, applies any overrides specified in the file at --override, then writes the map to the PHP file where the PHP --class is defined.')
31
            ->addOption(
32
                'source',
33
                null,
34
                InputOption::VALUE_REQUIRED,
35
                'URL or filename of the source map',
36
                MapUpdater::DEFAULT_SOURCE_FILE
37
            )
38
            ->addOption(
39
                'override',
40
                null,
41
                InputOption::VALUE_REQUIRED,
42
                'URL or filename of the override commands to execute',
43
                MapUpdater::getDefaultOverrideFile()
44
            )
45
            ->addOption(
46
                'class',
47
                null,
48
                InputOption::VALUE_REQUIRED,
49
                'The Fully Qualified Class Name of the PHP class storing the map',
50
                MapHandler::DEFAULT_MAP_CLASS
51
            )
52
        ;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    protected function execute(InputInterface $input, OutputInterface $output)
59
    {
60
        MapHandler::setDefaultMapClass($input->getOption('class'));
61
        $current_map = MapHandler::map();
62
        $updater = new MapUpdater();
63
64
        // Loads the map from the source file.
65
        try {
66
            $new_map = $updater->createMapFromSourceFile($input->getOption('source'));
67
        } catch (\RuntimeException $e) {
68
            $output->writeln('<error>' . $e->getMessage() . '</error>');
69
            exit(2);
70
        }
71
72
        // Applies the overrides.
73
        try {
74
            $content = file_get_contents($input->getOption('override'));
75
            $updater->applyOverrides($new_map, Yaml::parse($content));
0 ignored issues
show
Documentation introduced by
$new_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
76
        } catch (\Exception $e) {
77
            $output->writeln('<error>' . $e->getMessage() . '</error>');
78
            exit(2);
79
        }
80
81
        // Check if anything got changed.
82
        $write = false;
83
        try {
84
            $this->compareMaps($current_map, $new_map, 'types');
0 ignored issues
show
Documentation introduced by
$current_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$new_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
85
        } catch (\RuntimeException $e) {
86
            $output->writeln('<comment>Changes to MIME types mapping</comment>');
87
            $output->writeln($e->getMessage());
88
            $write = true;
89
        }
90
        try {
91
            $this->compareMaps($current_map, $new_map, 'extensions');
0 ignored issues
show
Documentation introduced by
$current_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$new_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
        } catch (\RuntimeException $e) {
93
            $output->writeln('<comment>Changes to extensions mapping</comment>');
94
            $output->writeln($e->getMessage());
95
            $write = true;
96
        }
97
98
        // If changed, save the new map to the PHP file.
99
        if ($write) {
100
            $updater->writeMapToPhpClassFile($new_map, $current_map->getFileName());
0 ignored issues
show
Bug introduced by
The method getFileName cannot be called on $current_map (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Documentation introduced by
$new_map is of type string, but the function expects a object<FileEye\MimeMap\Map\AbstractMap>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
101
            $output->writeln('<comment>Code updated.</comment>');
102
        } else {
103
            $output->writeln('<info>No changes to mapping.</info>');
104
        }
105
106
        // Reset the new map's map array.
107
        $new_map->reset();
0 ignored issues
show
Bug introduced by
The method reset cannot be called on $new_map (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
108
    }
109
110
    /**
111
     * Compares two type-to-extension maps by section.
112
     *
113
     * @param AbstractMap $old_map
114
     *   The first map to compare.
115
     * @param AbstractMap $new_map
116
     *   The second map to compare.
117
     * @param string $section
118
     *   The first-level array key to compare: 'types' or 'extensions'.
119
     *
120
     * @throws \RuntimeException with diff details if the maps differ.
121
     *
122
     * @return bool
123
     *   True if the maps are equal.
124
     */
125
    protected function compareMaps(AbstractMap $old_map, AbstractMap $new_map, $section)
126
    {
127
        $old_map->sort();
128
        $new_map->sort();
129
        $old = $old_map->getMapArray();
130
        $new = $new_map->getMapArray();
131
132
        $factory = new Factory;
133
        $comparator = $factory->getComparatorFor($old[$section], $new[$section]);
134
        try {
135
            $comparator->assertEquals($old[$section], $new[$section]);
136
            return true;
137
        } catch (ComparisonFailure $failure) {
138
            $old_string = var_export($old[$section], true);
139
            $new_string = var_export($new[$section], true);
140
            if (class_exists('\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder')) {
141
                $differ = new Differ(new UnifiedDiffOutputBuilder("--- Removed\n+++ Added\n"));
142
                throw new \RuntimeException($differ->diff($old_string, $new_string));
143
            } else {
144
                throw new \RuntimeException(' ');
145
            }
146
        }
147
    }
148
}
149