Completed
Push — develop ( 320c63...92592d )
by Tom
04:57
created

AbstractShowCommand::getVariableDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
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 $variableName => $variableValue) {
115
            $rows[$i] = array($variableName, $variableValue);
116
            if (
117
                true === $hasDescription &&
118
                isset($this->_importantVars[$variableName], $this->_importantVars[$variableName]['desc'])
119
            ) {
120
                $rows[$i][] = $this->formatDesc($this->_importantVars[$variableName]['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 $k => $r) {
129
            if (2 === count($r)) {
130
                $rows[$k] = $this->getVariableDescription($r);
131
            }
132
        }
133
        return $rows;
134
    }
135
136
    /**
137
     * Extend or modify this method to add descriptions to other variables
138
     *
139
     * @param array $row
140
     *
141
     * @return array
142
     */
143
    protected function getVariableDescription(array $row)
144
    {
145
        $row[] = '';
146
        return $row;
147
    }
148
149
    /**
150
     * Formats the description
151
     *
152
     * @param string $desc
153
     *
154
     * @return string
155
     */
156
    protected function formatDesc($desc)
157
    {
158
        $desc = preg_replace('~\s+~', ' ', $desc);
159
        return wordwrap($desc);
160
    }
161
162
    /**
163
     * @param array $header
164
     * @param array $rows
165
     */
166
    protected function renderTable(array $header, array $rows)
167
    {
168
        /** @var \N98\Util\Console\Helper\TableHelper $t */
169
        $t = $this->getHelper('table');
170
        $t->setHeaders($header)
171
            ->renderByFormat($this->_output, $rows, $this->_input->getOption('format'));
172
    }
173
174
    /**
175
     * @param string|null $variable
176
     */
177
    protected function initVariables($variable = null)
178
    {
179
        /** @var \N98\Util\Console\Helper\DatabaseHelper $database */
180
        $database = $this->getHelper('database');
181
        $this->_allVariables = $database->{$this->showMethod}($variable);
182
    }
183
184
    /**
185
     * @param array $vars
186
     *
187
     * @return array
188
     */
189
    protected function formatVariables(array $vars)
190
    {
191
        $rounding = (int) $this->_input->getOption('rounding');
192
        if ($rounding > -1) {
193
            foreach ($vars as $k => &$v) {
194
                if (true === $this->allowRounding($k)) {
195
                    $v = Filesystem::humanFileSize($v, $rounding);
196
                }
197
                if (isset($this->_specialFormat[$k])) {
198
                    $formatter = $this->_specialFormat[$k];
199
                    if (is_string($formatter) && method_exists($this, $formatter)) {
200
                        $formatter = array($this, $formatter);
201
                    }
202
                    $v = call_user_func($formatter, $v);
203
                }
204
            }
205
            unset($v);
206
        }
207
        $maxWidth = $this->getMaxValueWidth($vars);
208
        // align=right
209
        foreach ($vars as &$v) {
210
            $v = str_pad($v, $maxWidth, ' ', STR_PAD_LEFT);
211
        }
212
        return $vars;
213
    }
214
215
    /**
216
     * @param array $vars
217
     *
218
     * @return int
219
     */
220
    protected function getMaxValueWidth(array $vars)
221
    {
222
        $maxWidth = 0;
223
        foreach ($vars as $v) {
224
            $l = strlen($v);
225
            if ($l > $maxWidth) {
226
                $maxWidth = $l;
227
            }
228
        }
229
        return $maxWidth;
230
    }
231
232
    /**
233
     * @param string $name
234
     *
235
     * @return bool
236
     */
237
    abstract protected function allowRounding($name);
238
}
239