Completed
Push — master ( cf0859...e578ec )
by Insolita
01:34
created

DefaultController::printMetricData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 11
rs 10
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 count;
18
use function file_exists;
19
20
class DefaultController extends Controller
21
{
22
    public $defaultAction = 'summary';
23
    /**
24
     * @var CodeStatModule|Module
25
     **/
26
    public $module;
27
    
28
    public $color = true;
29
    
30
    protected $climate;
31
32
    private static $metricGroups = [
33
        'Common'=> Console::FG_GREEN,
34
        'Size'=> Console::FG_YELLOW,
35
        'Cyclomatic Complexity'=> Console::FG_PURPLE,
36
        'Dependencies'=> Console::FG_CYAN,
37
        'Structure'=> Console::FG_BLUE,
38
    ];
39
40
    public function __construct($id, Module $module, CLImate $CLImate, array $config = [])
41
    {
42
        $this->climate = $CLImate;
43
        parent::__construct($id, $module, $config);
44
    }
45
46
    /**
47
     *  Show summary from partial phploc statistic information per each defined group
48
     * @param bool $showErrors
49
     * @return int
50
     */
51
    public function actionSummary(bool $showErrors = false)
52
    {
53
        $service = $this->module->statService;
54
        $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

54
        /** @scrutinizer ignore-call */ 
55
        $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...
55
        foreach ($summary as $name => &$row) {
56
            $row = ['Group' => $name] + $row;
57
        }
58
        $total = $service->summaryStatistic($summary);
59
        $total = ['Group' => 'Total'] + $total;
60
        $summary = $summary + [$total];
61
        if ($this->color) {
62
            $summary = $this->colorize(array_values($summary));
63
        }
64
        $this->headline('YII-2 Code Statistic', 'lightYellow');
65
        $this->climate->table($summary);
66
67
        if($showErrors !== true){
68
           return ExitCode::OK;
69
        }
70
        $this->headline('Failed for resolve', 'lightYellow');
71
        if(!count($service->errorList())){
72
            $this->climate->info('Errors not found');
73
        }else{
74
            Output::arrayList($service->errorList());
75
        }
76
        return ExitCode::OK;
77
    }
78
79
    /**
80
     *  Return full phploc statistic per each defined group
81
     * @param string|null $groupName
82
     * @return int
83
     */
84
    public function actionAdvanced(?string $groupName = null):int
85
    {
86
        $service = $this->module->statService;
87
        $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

87
        $statistic = $service->makeAdvancedStatistic($this->module->prepareFiles(), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
88
        $this->headline('YII-2 Code Statistic', 'green');
89
90
        if ($groupName !== null && !isset($statistic[$groupName])) {
91
            $this->stderr('Undefined group ' . $groupName);
92
            return ExitCode::DATAERR;
93
        }
94
95
        foreach ($statistic as $group => $data) {
96
            if ($groupName !== null && $groupName !== $group) {
97
                continue;
98
            }
99
            $this->headline($group, 'lightYellow');
100
            $this->printMetricData($data);
101
            if ($groupName === null && !$this->confirm('Show next group?')) {
102
                break;
103
            }
104
        }
105
        return ExitCode::OK;
106
    }
107
108
    /**
109
     * Return  phploc statistic for all files
110
     * @return int
111
     */
112
    public function actionCommon():int
113
    {
114
        $service = $this->module->statService;
115
        $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

115
        $statistic = $service->makeCommonStatistic($this->module->prepareFiles(), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
116
        $this->headline('YII-2 Code Statistic', 'green');
117
        $this->printMetricData($statistic);
118
        return ExitCode::OK;
119
    }
120
121
    /**
122
     * Return  phploc statistic for concrete directory
123
     * @param string $dir - Path or path alias
124
     * @return int
125
     */
126
    public function actionDirectory(string $dir):int
127
    {
128
        $service = $this->module->statService;
129
        $dir = \Yii::getAlias($dir);
130
        if(!is_dir($dir)){
131
            $this->stderr('Directory not found by path '.$dir);
132
            return ExitCode::UNSPECIFIED_ERROR;
133
        }
134
        $statistic = $service->makeCommonStatistic(FileHelper::findFiles($dir, [
135
            'only' => ['*.php'],
136
            'caseSensitive' => false,
137
            'recursive' => true,
138
        ]), $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

138
        ]), /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
139
        $this->headline('YII-2 Code Statistic', 'green');
140
        $this->printMetricData($statistic);
141
        return ExitCode::OK;
142
    }
143
144
    /**
145
     * Return  phploc statistic for concrete file
146
     * @param string $filePath - Path or path alias
147
     * @return int
148
     */
149
    public function actionFile(string $filePath):int
150
    {
151
        $service = $this->module->statService;
152
        $filePath = \Yii::getAlias($filePath);
153
        if(!file_exists($filePath)){
154
            $this->stderr('File not found by path '.$filePath);
155
            return ExitCode::UNSPECIFIED_ERROR;
156
        }
157
        $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

157
        $statistic = $service->makeCommonStatistic([$filePath], /** @scrutinizer ignore-type */ $this->module->metrics);
Loading history...
158
        $this->headline('YII-2 Code Statistic', 'green');
159
        $this->printMetricData($statistic);
160
        return ExitCode::OK;
161
    }
162
163
    /**
164
     * Show files that will be processed accordingly module configuration
165
     */
166
    public function actionListFiles()
167
    {
168
        Output::info('The following files will be processed accordingly module configuration');
169
        $files = $this->module->prepareFiles();
170
        Output::arrayList($files);
171
        Output::separator();
172
        Output::info('Total: ' . count($files));
173
    }
174
175
    /**
176
     * Show available metrics
177
     */
178
    public function actionListMetrics()
179
    {
180
        foreach (CodestatService::$metricNames as $group =>$data)
181
        {
182
            $printData = array_flip($data);
183
            $printData[$group] = 'Group';
184
            $this->printMetricData($printData);
185
            Output::separator();
186
        }
187
    }
188
    
189
    protected function colorize(array $summary)
190
    {
191
        $colorized = [];
192
        foreach ($summary as $i => $row) {
193
            foreach ($row as $key => $value) {
194
                if ($key === 'Group') {
195
                    $value = $this->wrap($value, 'yellow');
196
                }
197
                if ($i == count($summary) - 1) {
198
                    $value = $this->wrap($value, 'light_cyan');
199
                }
200
                $key = $this->wrap($key, 'green');
201
                $colorized[$i][$key] = (string)$value;
202
            }
203
        }
204
        return $colorized;
205
    }
206
207
    protected function wrap($string, $color):string
208
    {
209
        return "<bold><$color>$string</$color></bold>";
210
    }
211
212
    protected function headline($string, $color):string
213
    {
214
        $this->climate->green()->border('=', 110)->$color()->tab(4)->out($string);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
215
    }
216
217
    /**
218
     * @param $data
219
     */
220
    private function printMetricData($data):void
221
    {
222
        foreach ($data as $index => $line) {
223
            if ($line === 'Group') {
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