Completed
Pull Request — master (#35)
by Robbie
02:18
created

DumpCommand::getParsedOutput()   C

Complexity

Conditions 8
Paths 4

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 28
rs 5.3846
cc 8
eloc 20
nc 4
nop 0
1
<?php
2
3
namespace SilverLeague\Console\Command\Config;
4
5
use SilverLeague\Console\Command\Config\AbstractConfigCommand;
6
use Symfony\Component\Console\Helper\Table;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Output\OutputInterface;
10
11
/**
12
 * Outputs a combined representation of all SilverStripe configuration
13
 *
14
 * @package silverstripe-console
15
 * @author  Robbie Averill <[email protected]>
16
 */
17
class DumpCommand extends AbstractConfigCommand
18
{
19
    /**
20
     * The supported configuration sources
21
     *
22
     * @var array
23
     */
24
    protected $configTypes = ['all', 'yaml', 'static', 'overrides'];
25
26
    /**
27
     * @var string
28
     */
29
    protected $configType;
30
31
    /**
32
     * @var string|null
33
     */
34
    protected $filter;
35
36
    /**
37
     * {@inheritDoc}
38
     */
39
    protected function configure()
40
    {
41
        $this
42
            ->setName('config:dump')
43
            ->setDescription(
44
                'Dumps all of the processed configuration properties and their values. You can optionally filter the'
45
                . ' type to control the source of data, for example use "yaml" to only return configuration values that'
46
                . ' were defined in YAML configuration files. You can also add the --filter option with a search value'
47
                . ' to narrow the results.'
48
            )
49
            ->addArgument('type', null, implode(', ', $this->configTypes), 'all')
50
            ->addOption('filter', null, InputOption::VALUE_REQUIRED, 'Filter the results (search)');
51
    }
52
53
    /**
54
     * {@inheritDoc}
55
     * @param InputInterface $input
56
     * @param OutputInterface $output
57
     * @throws InvalidArgumentException If an invalid configuration type is provided
58
     */
59
    protected function execute(InputInterface $input, OutputInterface $output)
60
    {
61
        if ($input->getArgument('type') && !in_array($input->getArgument('type'), $this->configTypes)) {
62
            throw new \InvalidArgumentException(
63
                sprintf(
64
                    '%s is not a valid config type, options: %s',
65
                    $input->getArgument('type'),
66
                    implode(', ', $this->configTypes)
67
                )
68
            );
69
        }
70
71
        $this->filter = $input->getOption('filter');
72
        $this->configType = $input->getArgument('type');
73
74
        $data = $this->getParsedOutput();
75
        if ($this->filter) {
76
            $data = $this->filterOutput($data, $this->filter);
77
        }
78
79
        $table = new Table($output);
80
        $table
81
            ->setHeaders(['Class name', 'Property', 'Key', 'Value'])
82
            ->setRows($data)
83
            ->render();
84
    }
85
86
    /**
87
     * Get source configuration data by the optional "type". If not provided, they will all be merged
88
     * together in the same manner as \SilverStripe\Core\Config\Config::getUncached
89
     *
90
     * @return array
91
     */
92
    protected function getSourceData()
93
    {
94
        $output = [];
0 ignored issues
show
Unused Code introduced by
$output is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95
        switch ($this->configType) {
96
            case 'yaml':
97
                $output = $this->getYamlConfig();
98
                break;
99
            case 'static':
100
                $output = $this->getStaticConfig();
101
                break;
102
            case 'overrides':
103
                $output = $this->getConfigOverrides();
104
                break;
105
            case 'all':
106
            default:
107
                // Statics are the lowest priority
108
                $output = $this->getStaticConfig();
109
                // Then YAML is added
110
                foreach ($this->getYamlConfig() as $class => $property) {
111
                    if (!array_key_exists($class, $output)) {
112
                        $output[$class] = [];
113
                    }
114
                    $output[$class] = array_merge($property, $output[$class]);
115
                }
116
                // Then overrides are added last
117
                foreach ($this->getConfigOverrides() as $class => $values) {
118
                    foreach ($values as $property => $value) {
119
                        $output[$class][$property] = $value;
120
                    }
121
                }
122
123
                break;
124
        }
125
        return $output;
126
    }
127
128
    /**
129
     * Creates a table-friendly output array from the input configuration sources
130
     *
131
     * @return array
132
     */
133
    protected function getParsedOutput()
134
    {
135
        $output = [];
136
        foreach ($this->getSourceData() as $className => $classInfo) {
137
            foreach ($classInfo as $property => $values) {
138
                $row = [$className, $property];
139
                if (is_array($values)) {
140
                    $temp = [];
0 ignored issues
show
Unused Code introduced by
$temp is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
141
                    foreach ($values as $key => $value) {
142
                        $row[] = is_numeric($key) ? '' : $key;
143
                        $row[] = is_array($value) ? json_encode($value, JSON_PRETTY_PRINT) : $value;
144
                        $output[] = $row;
145
                        // We need the class and property data for second level values if we're filtering.
146
                        if ($this->filter) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filter of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
147
                            $row = [$className, $property];
148
                        } else {
149
                            $row = ['', ''];
150
                        }
151
                    }
152
                } else {
153
                    $row[] = '';
154
                    $row[] = $values;
155
                }
156
                $output[] = $row;
157
            }
158
        }
159
        return $output;
160
    }
161
162
    /**
163
     * Apply a search filter to the results
164
     *
165
     * @param  array  $data   The pre-parsed output data
166
     * @param  string $filter The string to search on
167
     * @return array          Rows that have a string match on any of their fields
168
     */
169
    protected function filterOutput($data, $filter)
170
    {
171
        $output = [];
172
        foreach ($data as $values) {
173
            foreach ($values as $value) {
174
                if (is_string($value) && stripos($value, $filter) !== false) {
175
                    $output[] = $values;
176
                }
177
            }
178
        }
179
        return $output;
180
    }
181
}
182