Completed
Push — master ( 73e64d...d8efdb )
by Insolita
06:57
created

DefaultController::actionAdvanced()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 4
nop 1
dl 0
loc 18
rs 9.2222
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by solly [18.10.17 4:41]
4
 */
5
6
namespace insolita\codestat\controllers;
7
8
use insolita\codestat\CodeStatModule;
9
use insolita\codestat\helpers\Output;
10
use insolita\codestat\lib\CodestatService;
11
use League\CLImate\CLImate;
12
use yii\base\Module;
13
use yii\console\Controller;
14
use yii\console\ExitCode;
15
use yii\helpers\Console;
16
use yii\helpers\FileHelper;
17
use function array_flip;
18
use function count;
19
use function file_exists;
20
21
class DefaultController extends Controller
22
{
23
    public $defaultAction = 'summary';
24
    /**
25
     * @var CodeStatModule|Module
26
     **/
27
    public $module;
28
    
29
    public $color = true;
30
    
31
    protected $climate;
32
33
    private static $metricGroups = [
34
        'Common'=> Console::FG_GREEN,
35
        'Size'=> Console::FG_YELLOW,
36
        'Cyclomatic Complexity'=> Console::FG_PURPLE,
37
        'Dependencies'=> Console::FG_CYAN,
38
        'Structure'=> Console::FG_BLUE,
39
    ];
40
41
    public function __construct($id, Module $module, CLImate $CLImate, array $config = [])
42
    {
43
        $this->climate = $CLImate;
44
        parent::__construct($id, $module, $config);
45
    }
46
47
    /**
48
     *  Show summary from partial phploc statistic information per each defined group
49
     * @param bool $showErrors
50
     * @return int
51
     */
52
    public function actionSummary(bool $showErrors = false)
53
    {
54
        $service = $this->module->statService;
55
        $summary = $service->makeStatistic($this->module->prepareFiles());
0 ignored issues
show
Bug introduced by
The method makeStatistic() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
        /** @scrutinizer ignore-call */ 
56
        $summary = $service->makeStatistic($this->module->prepareFiles());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
56
        foreach ($summary as $name => &$row) {
57
            $row = ['Group' => $name] + $row;
58
        }
59
        $total = $service->summaryStatistic($summary);
60
        $total = ['Group' => 'Total'] + $total;
61
        $summary = $summary + [$total];
62
        if ($this->color) {
63
            $summary = $this->colorize(array_values($summary));
64
        }
65
        $this->headline('YII-2 Code Statistic', 'lightYellow');
66
        $this->climate->table($summary);
67
68
        if($showErrors !== true){
69
            return ExitCode::OK;
70
        }
71
        $this->headline('Failed for resolve', 'lightYellow');
72
        if(!count($service->errorList())){
73
            $this->climate->info('Errors not found');
74
        } else{
75
            Output::arrayList($service->errorList());
76
        }
77
        return ExitCode::OK;
78
    }
79
80
    /**
81
     *  Return full phploc statistic per each defined group
82
     * @param array $groupNames
83
     * @return int
84
     */
85
    public function actionAdvanced(array $groupNames = []):int
86
    {
87
        $service = $this->module->statService;
88
        $statistic = $service->makeAdvancedStatistic($this->module->prepareFiles(), $this->module->metrics);
0 ignored issues
show
Bug introduced by
It seems like $this->module->metrics can also be of type null and object; however, parameter $metrics of insolita\codestat\lib\co...makeAdvancedStatistic() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

88
        $statistic = $service->makeAdvancedStatistic($this->module->prepareFiles(), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
89
        $this->headline('YII-2 Code Statistic', 'green');
90
91
92
        foreach ($statistic as $group => $data) {
93
            if (!empty($groupNames) && !in_array($group, $groupNames, true)) {
94
                continue;
95
            }
96
            $this->headline($group, 'lightYellow');
97
            $this->printMetricData($data);
98
            if (empty($groupNames) && !$this->confirm('Show next group?', true)) {
99
                break;
100
            }
101
        }
102
        return ExitCode::OK;
103
    }
104
105
    /**
106
     * Return  phploc statistic for all files
107
     * @return int
108
     */
109
    public function actionCommon():int
110
    {
111
        $service = $this->module->statService;
112
        $statistic = $service->makeCommonStatistic($this->module->prepareFiles(), $this->module->metrics);
0 ignored issues
show
Bug introduced by
It seems like $this->module->metrics can also be of type null and object; however, parameter $metrics of insolita\codestat\lib\co...::makeCommonStatistic() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
        $statistic = $service->makeCommonStatistic($this->module->prepareFiles(), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
113
        $this->headline('YII-2 Code Statistic', 'green');
114
        $this->printMetricData($statistic, !empty($this->module->metrics));
115
        return ExitCode::OK;
116
    }
117
118
    /**
119
     * Return  phploc statistic for concrete directory
120
     * @param string $dir - Path or path alias
121
     * @return int
122
     */
123
    public function actionDirectory(string $dir):int
124
    {
125
        $service = $this->module->statService;
126
        $dir = \Yii::getAlias($dir);
127
        if (!is_dir($dir)) {
128
            $this->stderr('Directory not found by path ' . $dir);
129
            return ExitCode::UNSPECIFIED_ERROR;
130
        }
131
        $statistic = $service->makeCommonStatistic(FileHelper::findFiles($dir, [
132
            'only' => ['*.php'],
133
            'caseSensitive' => false,
134
            'recursive' => true,
135
        ]), $this->module->metrics);
0 ignored issues
show
Bug introduced by
It seems like $this->module->metrics can also be of type null and object; however, parameter $metrics of insolita\codestat\lib\co...::makeCommonStatistic() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

135
        ]), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
136
        $this->headline('YII-2 Code Statistic', 'green');
137
        $this->printMetricData($statistic, !empty($this->module->metrics));
138
        return ExitCode::OK;
139
    }
140
141
    /**
142
     * Return  phploc statistic for concrete file
143
     * @param string $filePath - Path or path alias
144
     * @return int
145
     */
146
    public function actionFile(string $filePath):int
147
    {
148
        $service = $this->module->statService;
149
        $filePath = \Yii::getAlias($filePath);
150
        if (!file_exists($filePath)) {
151
            $this->stderr('File not found by path ' . $filePath);
152
            return ExitCode::UNSPECIFIED_ERROR;
153
        }
154
        $statistic = $service->makeCommonStatistic([$filePath], $this->module->metrics);
0 ignored issues
show
Bug introduced by
It seems like $this->module->metrics can also be of type null and object; however, parameter $metrics of insolita\codestat\lib\co...::makeCommonStatistic() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

154
        $statistic = $service->makeCommonStatistic([$filePath], /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
155
        $this->headline('YII-2 Code Statistic', 'green');
156
        $this->printMetricData($statistic, !empty($this->module->metrics));
157
        return ExitCode::OK;
158
    }
159
160
    /**
161
     * Show files that will be processed accordingly module configuration
162
     */
163
    public function actionListFiles()
164
    {
165
        Output::info('The following files will be processed accordingly module configuration');
166
        $files = $this->module->prepareFiles();
167
        Output::arrayList($files);
168
        Output::separator();
169
        Output::info('Total: ' . count($files));
170
    }
171
172
    /**
173
     * Show available metrics
174
     */
175
    public function actionListMetrics()
176
    {
177
        foreach (CodestatService::$metricNames as $group =>$data)
178
        {
179
            $printData = array_merge([$group => 'Group'], array_flip($data));
180
            $this->printMetricData($printData);
181
            Output::separator();
182
        }
183
    }
184
    
185
    protected function colorize(array $summary):array
186
    {
187
        $colorized = [];
188
        foreach ($summary as $i => $row) {
189
            foreach ($row as $key => $value) {
190
                if ($key === 'Group') {
191
                    $value = $this->wrap($value, 'yellow');
192
                }
193
                if ($i == count($summary) - 1) {
194
                    $value = $this->wrap($value, 'light_cyan');
195
                }
196
                $key = $this->wrap($key, 'green');
197
                $colorized[$i][$key] = (string) $value;
198
            }
199
        }
200
        return $colorized;
201
    }
202
203
    protected function wrap($string, $color):string
204
    {
205
        return "<bold><$color>$string</$color></bold>";
206
    }
207
208
    protected function headline($string, $color):void
209
    {
210
        $this->climate->green()->border('=', 110)->$color()->tab(4)->out($string);
211
    }
212
213
    /**
214
     * @param      $data
215
     * @param bool $skipHeaders
216
     */
217
    private function printMetricData($data, bool $skipHeaders = false):void
218
    {
219
        foreach ($data as $index => $line) {
220
            if ($line === 'Group') {
221
                if($skipHeaders === true){
222
                    continue;
223
                }
224
                $this->stdout($index, self::$metricGroups[$index], Console::BOLD);
225
                $this->stdout(PHP_EOL);
226
                Output::separator();
227
                continue;
228
            }
229
            $this->stdout(' ' . $index . '  ', Console::BOLD);
230
            $this->stdout($line . PHP_EOL);
231
        }
232
    }
233
}
234