Completed
Push — master ( 92bd35...fb5c6c )
by Tom
04:10
created

AbstractShowCommand::formatVariables()   C

Complexity

Conditions 8
Paths 4

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
c 0
b 0
f 0
rs 5.3846
cc 8
eloc 16
nc 4
nop 1
1
<?php
2
3
namespace N98\Magento\Command\Database;
4
5
use N98\Util\Console\Helper\Table\Renderer\RendererFactory;
6
use N98\Util\Filesystem;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
abstract class AbstractShowCommand extends AbstractDatabaseCommand
13
{
14
    protected $showMethod = 'getGlobalVariables';
15
16
    /**
17
     * @var \Symfony\Component\Console\Input\InputInterface
18
     */
19
    protected $_input = null;
20
21
    /**
22
     * @var \Symfony\Component\Console\Output\OutputInterface
23
     */
24
    protected $_output = null;
25
26
    /**
27
     * @var array
28
     */
29
    protected $_importantVars = array();
30
31
    /**
32
     * Key = variable name => value method name in this class
33
     *
34
     * @var array
35
     */
36
    protected $_specialFormat = array();
37
38
    /**
39
     * Contains all variables
40
     *
41
     * @var array
42
     */
43
    protected $_allVariables = array();
44
45
    protected function configure()
46
    {
47
        parent::configure();
48
        $this
49
            ->addArgument(
50
                'search',
51
                InputArgument::OPTIONAL,
52
                'Only output variables of specified name. The wildcard % is supported!'
53
            )
54
            ->addOption(
55
                'format',
56
                null,
57
                InputOption::VALUE_OPTIONAL,
58
                'Output Format. One of [' . implode(',', RendererFactory::getFormats()) . ']'
59
            )
60
            ->addOption(
61
                'rounding',
62
                null,
63
                InputOption::VALUE_OPTIONAL,
64
                'Amount of decimals to display. If -1 then disabled',
65
                0
66
            )
67
            ->addOption(
68
                'no-description',
69
                null,
70
                InputOption::VALUE_NONE,
71
                'Disable description'
72
            );
73
    }
74
75
    /**
76
     * @param \Symfony\Component\Console\Input\InputInterface   $input
77
     * @param \Symfony\Component\Console\Output\OutputInterface $output
78
     *
79
     * @throws \InvalidArgumentException
80
     * @return void
81
     */
82
    protected function execute(InputInterface $input, OutputInterface $output)
83
    {
84
        $this->_input = $input;
85
        $this->_output = $output;
86
        $this->initVariables($this->_input->getArgument('search'));
87
        $outputVars = $this->_allVariables;
88
        if (null === $this->_input->getArgument('search')) {
89
            $outputVars = array_intersect_key($this->_allVariables, $this->_importantVars);
90
        }
91
92
        $outputVars = $this->formatVariables($outputVars);
93
        reset($this->_importantVars);
94
        $hasDescription = isset($this->_importantVars[key($this->_importantVars)]['desc']) &&
95
            false === $this->_input->getOption('no-description');
96
        $header = array('Variable Name', 'Value');
97
        if (true === $hasDescription) {
98
            $header[] = 'Description';
99
        }
100
101
        $this->renderTable($header, $this->generateRows($outputVars, $hasDescription));
102
    }
103
104
    /**
105
     * @param array $outputVars
106
     * @param bool  $hasDescription
107
     *
108
     * @return array
109
     */
110
    protected function generateRows(array $outputVars, $hasDescription)
111
    {
112
        $rows = array();
113
        $i = 0;
114
        foreach ($outputVars as $name => $value) {
115
            $rows[$i] = array($name, $value);
116
            if (
117
                true === $hasDescription &&
118
                isset($this->_importantVars[$name]['desc'])
119
            ) {
120
                $rows[$i][] = $this->formatDesc($this->_importantVars[$name]['desc']);
121
            }
122
            $i++;
123
        }
124
        // when searching no every variable has a description so fill the missing ones with blanks
125
        if (false === $hasDescription) {
126
            return $rows;
127
        }
128
        foreach ($rows as $i => $row) {
129
            if (2 === count($row)) {
130
                $rows[$i] = $this->getVariableDescription($row);
131
            }
132
        }
133
134
        return $rows;
135
    }
136
137
    /**
138
     * Extend or modify this method to add descriptions to other variables
139
     *
140
     * @param array $row
141
     *
142
     * @return array
143
     */
144
    protected function getVariableDescription(array $row)
145
    {
146
        $row[] = '';
147
        return $row;
148
    }
149
150
    /**
151
     * Formats the description
152
     *
153
     * @param string $desc
154
     *
155
     * @return string
156
     */
157
    protected function formatDesc($desc)
158
    {
159
        $desc = preg_replace('~\s+~', ' ', $desc);
160
        return wordwrap($desc);
161
    }
162
163
    /**
164
     * @param array $header
165
     * @param array $rows
166
     */
167
    protected function renderTable(array $header, array $rows)
168
    {
169
        /** @var \N98\Util\Console\Helper\TableHelper $t */
170
        $t = $this->getHelper('table');
171
        $t->setHeaders($header)
172
            ->renderByFormat($this->_output, $rows, $this->_input->getOption('format'));
173
    }
174
175
    /**
176
     * @param string|null $variable
177
     */
178
    protected function initVariables($variable = null)
179
    {
180
        /** @var \N98\Util\Console\Helper\DatabaseHelper $database */
181
        $database = $this->getHelper('database');
182
        $this->_allVariables = $database->{$this->showMethod}($variable);
183
    }
184
185
    /**
186
     * @param array $vars
187
     *
188
     * @return array
189
     */
190
    protected function formatVariables(array $vars)
191
    {
192
        $rounding = (int) $this->_input->getOption('rounding');
193
        if ($rounding > -1) {
194
            foreach ($vars as $k => &$v) {
195
                if (true === $this->allowRounding($k)) {
196
                    $v = Filesystem::humanFileSize($v, $rounding);
197
                }
198
                if (isset($this->_specialFormat[$k])) {
199
                    $formatter = $this->_specialFormat[$k];
200
                    if (is_string($formatter) && method_exists($this, $formatter)) {
201
                        $formatter = array($this, $formatter);
202
                    }
203
                    $v = call_user_func($formatter, $v);
204
                }
205
            }
206
            unset($v);
207
        }
208
        $maxWidth = $this->getMaxValueWidth($vars);
209
        // align=right
210
        foreach ($vars as &$v) {
211
            $v = str_pad($v, $maxWidth, ' ', STR_PAD_LEFT);
212
        }
213
        return $vars;
214
    }
215
216
    /**
217
     * @param array $vars
218
     *
219
     * @return int
220
     */
221
    protected function getMaxValueWidth(array $vars)
222
    {
223
        $maxWidth = 0;
224
        foreach ($vars as $v) {
225
            $l = strlen($v);
226
            if ($l > $maxWidth) {
227
                $maxWidth = $l;
228
            }
229
        }
230
        return $maxWidth;
231
    }
232
233
    /**
234
     * @param string $name
235
     *
236
     * @return bool
237
     */
238
    abstract protected function allowRounding($name);
239
}
240