DumpCommand::getParsedOutput()   C
last analyzed

Complexity

Conditions 12
Paths 6

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 39
rs 6.9666
c 0
b 0
f 0
cc 12
nc 6
nop 1

How to fix   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 SilverLeague\Console\Command\Config;
4
5
use SilverStripe\Core\Convert;
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
     * @var string|null
21
     */
22
    protected $filter;
23
24
    /**
25
     * {@inheritDoc}
26
     */
27
    protected function configure()
28
    {
29
        $this
30
            ->setName('config:dump')
31
            ->setDescription('Dumps all of the processed configuration properties and their values')
32
            ->addOption('filter', null, InputOption::VALUE_REQUIRED, 'Filter the results (search)');
33
34
        $this->setHelp(<<<HELP
35
Dumps all of the processed configuration properties and their values. You can optionally add the --filter option
36
with a search value to narrow the results.
37
HELP
38
        );
39
    }
40
41
    /**
42
     * {@inheritDoc}
43
     * @param InputInterface $input
44
     * @param OutputInterface $output
45
     * @throws InvalidArgumentException If an invalid configuration type is provided
46
     */
47
    protected function execute(InputInterface $input, OutputInterface $output)
48
    {
49
        $this->filter = $input->getOption('filter');
0 ignored issues
show
Documentation Bug introduced by
It seems like $input->getOption('filter') can also be of type array<integer,string> or boolean. However, the property $filter is declared as type string|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
50
51
        $data = $this->getParsedOutput($this->getConfig()->getAll());
52
        if ($this->filter) {
53
            $data = $this->filterOutput($data, $this->filter);
54
        }
55
56
        $table = new Table($output);
57
        $table
58
            ->setHeaders(['Class name', 'Property', 'Key', 'Value'])
59
            ->setRows($data)
60
            ->render();
61
    }
62
63
    /**
64
     * Creates a table-friendly output array from the input configuration source
65
     *
66
     * @param  array $data
67
     * @return array
68
     */
69
    protected function getParsedOutput($data)
70
    {
71
        $output = [];
72
        foreach ($data as $className => $classInfo) {
73
            foreach ($classInfo as $property => $values) {
74
                $row = [$className, $property];
75
                if (is_array($values) || is_object($values)) {
76
                    foreach ($values as $key => $value) {
77
                        $row[] = is_numeric($key) ? '' : $key;
78
                        if (is_array($value)) {
79
                            $value = Convert::raw2json($value, JSON_PRETTY_PRINT);
80
                        } elseif (is_object($value)) {
81
                            $value = get_class($value);
82
                        } else {
83
                            $value = (string) $value;
84
                        }
85
                        $row[] = $value;
86
                        if (array_filter($row) != []) {
87
                            $output[] = $row;
88
                        }
89
                        // We need the class and property data for second level values if we're filtering.
90
                        if ($this->filter !== null) {
91
                            $row = [$className, $property];
92
                        } else {
93
                            $row = ['', ''];
94
                        }
95
                    }
96
                } else {
97
                    $row[] = '';
98
                    $row[] = $values;
99
                }
100
101
                if (array_filter($row) != []) {
102
                    $output[] = $row;
103
                }
104
            }
105
        }
106
        return $output;
107
    }
108
109
    /**
110
     * Apply a search filter to the results
111
     *
112
     * @param  array  $data   The pre-parsed output data
113
     * @param  string $filter The string to search on
114
     * @return array          Rows that have a string match on any of their fields
115
     */
116
    protected function filterOutput($data, $filter)
117
    {
118
        $output = [];
119
        foreach ($data as $values) {
120
            foreach ($values as $value) {
121
                if (is_string($value) && stripos($value, $filter) !== false) {
122
                    $output[] = $values;
123
                }
124
            }
125
        }
126
        return $output;
127
    }
128
}
129