LaravelSCommand   F
last analyzed

Complexity

Total Complexity 74

Size/Duplication

Total Lines 330
Duplicated Lines 0 %

Importance

Changes 10
Bugs 2 Features 1
Metric Value
eloc 196
c 10
b 2
f 1
dl 0
loc 330
rs 2.48
wmc 74

13 Methods

Rating   Name   Duplication   Size   Complexity  
C publish() 0 59 12
A showLogo() 0 13 1
A isLumen() 0 3 1
A fire() 0 3 1
A getConfigPath() 0 3 1
A preCheck() 0 14 6
A prepareConfig() 0 31 4
A loadConfig() 0 6 4
A handle() 0 22 6
F preSet() 0 47 18
A showInfo() 0 6 1
B showComponents() 0 31 7
C showProtocols() 0 54 12

How to fix   Complexity   

Complex Class

Complex classes like LaravelSCommand often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LaravelSCommand, and based on these observations, apply Extract Interface, too.

1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace Hhxsv5\LaravelS\Illuminate;
4
5
use Hhxsv5\LaravelS\Components\Prometheus\CollectorProcess;
6
use Hhxsv5\LaravelS\Components\Prometheus\TimerProcessMetricsCronJob;
7
use Illuminate\Console\Command;
0 ignored issues
show
Bug introduced by
The type Illuminate\Console\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Illuminate\Support\Arr;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Arr was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
class LaravelSCommand extends Command
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class LaravelSCommand
Loading history...
11
{
12
    protected $signature = 'laravels {action? : publish|config|info}
13
    {--d|daemonize : Run as a daemon}
14
    {--i|ignore : Ignore checking PID file of Master process}
15
    {--x=|x-version= : The version(branch) of the current project, stored in $_ENV/$_SERVER}';
16
17
    protected $description = 'LaravelS console tool';
18
19
    public function fire()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function fire()
Loading history...
20
    {
21
        $this->handle();
22
    }
23
24
    public function handle()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function handle()
Loading history...
25
    {
26
        $action = (string)$this->argument('action');
27
        switch ($action) {
28
            case 'publish':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
29
                $this->publish();
30
                break;
31
            case 'config':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
32
            case 'info':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
33
                $this->prepareConfig();
34
                $this->showInfo();
35
                break;
36
            default:
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
37
                $this->info(sprintf('Usage: [%s] ./artisan laravels publish|config|info', PHP_BINARY));
38
                if (in_array($action, ['start', 'stop', 'restart', 'reload'], true)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
39
                    $this->error(sprintf(
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
40
                        'The "%s" command has been migrated to "bin/laravels", %ssee https://github.com/hhxsv5/laravel-s#run',
41
                        $action,
42
                        file_exists(base_path('bin/laravels')) ? '' : 'please run `php artisan laravels publish` first, '
0 ignored issues
show
Bug introduced by
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

42
                        file_exists(/** @scrutinizer ignore-call */ base_path('bin/laravels')) ? '' : 'please run `php artisan laravels publish` first, '
Loading history...
43
                    ));
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
44
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
45
                break;
46
        }
47
    }
48
49
    protected function isLumen()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function isLumen()
Loading history...
50
    {
51
        return stripos($this->getApplication()->getVersion(), 'Lumen') !== false;
52
    }
53
54
    protected function loadConfig()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function loadConfig()
Loading history...
55
    {
56
        // Load configuration laravel.php manually for Lumen
57
        $basePath = config('laravels.laravel_base_path') ?: base_path();
0 ignored issues
show
Bug introduced by
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

57
        $basePath = config('laravels.laravel_base_path') ?: /** @scrutinizer ignore-call */ base_path();
Loading history...
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

57
        $basePath = /** @scrutinizer ignore-call */ config('laravels.laravel_base_path') ?: base_path();
Loading history...
58
        if ($this->isLumen() && file_exists($basePath . '/config/laravels.php')) {
59
            $this->getLaravel()->configure('laravels');
60
        }
61
    }
62
63
    protected function showInfo()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function showInfo()
Loading history...
64
    {
65
        $this->showLogo();
66
        $this->showComponents();
67
        $this->showProtocols();
68
        $this->comment('>>> Feedback: <options=underscore>https://github.com/hhxsv5/laravel-s</>');
69
    }
70
71
    protected function showLogo()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function showLogo()
Loading history...
72
    {
73
        static $logo = <<<EOS
74
 _                               _  _____ 
75
| |                             | |/ ____|
76
| |     __ _ _ __ __ ___   _____| | (___  
77
| |    / _` | '__/ _` \ \ / / _ \ |\___ \ 
78
| |___| (_| | | | (_| |\ V /  __/ |____) |
79
|______\__,_|_|  \__,_| \_/ \___|_|_____/ 
80
                                           
81
EOS;
82
        $this->info($logo);
83
        $this->info('Speed up your Laravel/Lumen');
84
    }
85
86
    protected function showComponents()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function showComponents()
Loading history...
87
    {
88
        $this->comment('>>> Components');
89
        $laravelSVersion = '-';
90
        $lockFile = base_path('composer.lock');
0 ignored issues
show
Bug introduced by
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

90
        $lockFile = /** @scrutinizer ignore-call */ base_path('composer.lock');
Loading history...
91
        $cfg = file_exists($lockFile) ? json_decode(file_get_contents($lockFile), true) : [];
92
        if (isset($cfg['packages'])) {
93
            $packages = array_merge($cfg['packages'], Arr::get($cfg, 'packages-dev', []));
94
            foreach ($packages as $package) {
95
                if (isset($package['name']) && $package['name'] === 'hhxsv5/laravel-s') {
96
                    $laravelSVersion = ltrim($package['version'], 'vV');
97
                    break;
98
                }
99
            }
100
        }
101
        $this->table(['Component', 'Version'], [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
102
            [
103
                'PHP',
104
                PHP_VERSION,
105
            ],
106
            [
107
                extension_loaded('openswoole') ? 'Open Swoole' : 'Swoole',
108
                SWOOLE_VERSION,
109
            ],
110
            [
111
                'LaravelS',
112
                $laravelSVersion,
113
            ],
114
            [
115
                $this->getApplication()->getName() . ' [<info>' . env('APP_ENV', config('app.env')) . '</info>]',
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

115
                $this->getApplication()->getName() . ' [<info>' . env('APP_ENV', /** @scrutinizer ignore-call */ config('app.env')) . '</info>]',
Loading history...
Bug introduced by
The function env was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

115
                $this->getApplication()->getName() . ' [<info>' . /** @scrutinizer ignore-call */ env('APP_ENV', config('app.env')) . '</info>]',
Loading history...
116
                $this->getApplication()->getVersion(),
117
            ],
118
        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
119
    }
120
121
    protected function showProtocols()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function showProtocols()
Loading history...
122
    {
123
        $this->comment('>>> Protocols');
124
125
        $config = unserialize((string)file_get_contents($this->getConfigPath()));
126
        $ssl = isset($config['server']['swoole']['ssl_key_file'], $config['server']['swoole']['ssl_cert_file']);
127
        $socketType = isset($config['server']['socket_type']) ? $config['server']['socket_type'] : SWOOLE_SOCK_TCP;
128
        if (in_array($socketType, [SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_UNIX_STREAM])) {
129
            $listenAt = $config['server']['listen_ip'];
130
        } else {
131
            $listenAt = sprintf('%s:%s', $config['server']['listen_ip'], $config['server']['listen_port']);
132
        }
133
134
        $tableRows = [
135
            [
136
                'Main HTTP',
137
                '<info>On</info>',
138
                $this->isLumen() ? 'Lumen Router' : 'Laravel Router',
139
                sprintf('%s://%s', $ssl ? 'https' : 'http', $listenAt),
140
            ],
141
        ];
142
        if (!empty($config['server']['websocket']['enable'])) {
143
            $tableRows [] = [
144
                'Main WebSocket',
145
                '<info>On</info>',
146
                $config['server']['websocket']['handler'],
147
                sprintf('%s://%s', $ssl ? 'wss' : 'ws', $listenAt),
148
            ];
149
        }
150
151
        $socketTypeNames = [
152
            SWOOLE_SOCK_TCP         => 'TCP IPV4 Socket',
153
            SWOOLE_SOCK_TCP6        => 'TCP IPV6 Socket',
154
            SWOOLE_SOCK_UDP         => 'UDP IPV4 Socket',
155
            SWOOLE_SOCK_UDP6        => 'TCP IPV6 Socket',
156
            SWOOLE_SOCK_UNIX_DGRAM  => 'Unix Socket Dgram',
157
            SWOOLE_SOCK_UNIX_STREAM => 'Unix Socket Stream',
158
        ];
159
        $sockets = isset($config['server']['sockets']) ? $config['server']['sockets'] : [];
160
        foreach ($sockets as $key => $socket) {
161
            if (isset($socket['enable']) && !$socket['enable']) {
162
                continue;
163
            }
164
165
            $name = 'Port#' . $key . ' ';
166
            $name .= isset($socketTypeNames[$socket['type']]) ? $socketTypeNames[$socket['type']] : 'Unknown socket';
167
            $tableRows [] = [
168
                $name,
169
                '<info>On</info>',
170
                $socket['handler'],
171
                sprintf('%s:%s', $socket['host'], $socket['port']),
172
            ];
173
        }
174
        $this->table(['Protocol', 'Status', 'Handler', 'Listen At'], $tableRows);
175
    }
176
177
    protected function prepareConfig()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function prepareConfig()
Loading history...
178
    {
179
        $this->loadConfig();
180
181
        $svrConf = config('laravels');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

181
        $svrConf = /** @scrutinizer ignore-call */ config('laravels');
Loading history...
182
183
        $this->preSet($svrConf);
184
185
        $ret = $this->preCheck($svrConf);
186
        if ($ret !== 0) {
187
            return $ret;
188
        }
189
190
        // Fixed $_ENV['APP_ENV']
191
        if (isset($_SERVER['APP_ENV'])) {
192
            $_ENV['APP_ENV'] = $_SERVER['APP_ENV'];
193
        }
194
195
        $laravelConf = [
196
            'root_path'           => $svrConf['laravel_base_path'],
197
            'static_path'         => $svrConf['swoole']['document_root'],
198
            'cleaners'            => array_unique((array)Arr::get($svrConf, 'cleaners', [])),
199
            'register_providers'  => array_unique((array)Arr::get($svrConf, 'register_providers', [])),
200
            'destroy_controllers' => Arr::get($svrConf, 'destroy_controllers', []),
201
            'is_lumen'            => $this->isLumen(),
202
            '_SERVER'             => $_SERVER,
203
            '_ENV'                => $_ENV,
204
        ];
205
206
        $config = ['server' => $svrConf, 'laravel' => $laravelConf];
207
        return file_put_contents($this->getConfigPath(), serialize($config)) > 0 ? 0 : 1;
208
    }
209
210
    protected function getConfigPath()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getConfigPath()
Loading history...
211
    {
212
        return storage_path('laravels.conf');
0 ignored issues
show
Bug introduced by
The function storage_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

212
        return /** @scrutinizer ignore-call */ storage_path('laravels.conf');
Loading history...
213
    }
214
215
    protected function preSet(array &$svrConf)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function preSet()
Loading history...
216
    {
217
        if (!isset($svrConf['enable_gzip'])) {
218
            $svrConf['enable_gzip'] = false;
219
        }
220
        if (empty($svrConf['laravel_base_path'])) {
221
            $svrConf['laravel_base_path'] = base_path();
0 ignored issues
show
Bug introduced by
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

221
            $svrConf['laravel_base_path'] = /** @scrutinizer ignore-call */ base_path();
Loading history...
222
        }
223
        if (empty($svrConf['process_prefix'])) {
224
            $svrConf['process_prefix'] = trim(config('app.name', '') . ' ' . $svrConf['laravel_base_path']);
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

224
            $svrConf['process_prefix'] = trim(/** @scrutinizer ignore-call */ config('app.name', '') . ' ' . $svrConf['laravel_base_path']);
Loading history...
225
        }
226
        if ($this->option('ignore')) {
227
            $svrConf['ignore_check_pid'] = true;
228
        } elseif (!isset($svrConf['ignore_check_pid'])) {
229
            $svrConf['ignore_check_pid'] = false;
230
        }
231
        if (empty($svrConf['swoole']['document_root'])) {
232
            $svrConf['swoole']['document_root'] = $svrConf['laravel_base_path'] . '/public';
233
        }
234
        if ($this->option('daemonize')) {
235
            $svrConf['swoole']['daemonize'] = true;
236
        } elseif (!isset($svrConf['swoole']['daemonize'])) {
237
            $svrConf['swoole']['daemonize'] = false;
238
        }
239
        if (empty($svrConf['swoole']['pid_file'])) {
240
            $svrConf['swoole']['pid_file'] = storage_path('laravels.pid');
0 ignored issues
show
Bug introduced by
The function storage_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

240
            $svrConf['swoole']['pid_file'] = /** @scrutinizer ignore-call */ storage_path('laravels.pid');
Loading history...
241
        }
242
        if (empty($svrConf['timer']['max_wait_time'])) {
243
            $svrConf['timer']['max_wait_time'] = 5;
244
        }
245
246
        // Configure TimerProcessMetricsCronJob automatically
247
        if (isset($svrConf['processes']) && !empty($svrConf['timer']['enable'])) {
248
            foreach ($svrConf['processes'] as $process) {
249
                if ($process['class'] === CollectorProcess::class && (!isset($process['enable']) || $process['enable'])) {
250
                    $svrConf['timer']['jobs'][] = TimerProcessMetricsCronJob::class;
251
                    break;
252
                }
253
            }
254
        }
255
256
        // Set X-Version
257
        $xVersion = (string)$this->option('x-version');
258
        if ($xVersion !== '') {
259
            $_SERVER['X_VERSION'] = $_ENV['X_VERSION'] = $xVersion;
260
        }
261
        return 0;
262
    }
263
264
    protected function preCheck(array $svrConf)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function preCheck()
Loading history...
265
    {
266
        if (!empty($svrConf['enable_gzip']) && version_compare(SWOOLE_VERSION, '4.1.0', '>=')) {
267
            $this->error('enable_gzip is DEPRECATED since Swoole 4.1.0, set http_compression of Swoole instead, http_compression is disabled by default.');
268
            $this->info('If there is a proxy server like Nginx, suggest that enable gzip in Nginx and disable gzip in Swoole, to avoid the repeated gzip compression for response.');
269
            return 1;
270
        }
271
        if (!empty($svrConf['events'])) {
272
            if (empty($svrConf['swoole']['task_worker_num']) || $svrConf['swoole']['task_worker_num'] <= 0) {
273
                $this->error('Asynchronous event listening needs to set task_worker_num > 0');
274
                return 1;
275
            }
276
        }
277
        return 0;
278
    }
279
280
281
    public function publish()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function publish()
Loading history...
282
    {
283
        $basePath = config('laravels.laravel_base_path') ?: base_path();
0 ignored issues
show
Bug introduced by
The function base_path was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

283
        $basePath = config('laravels.laravel_base_path') ?: /** @scrutinizer ignore-call */ base_path();
Loading history...
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

283
        $basePath = /** @scrutinizer ignore-call */ config('laravels.laravel_base_path') ?: base_path();
Loading history...
284
        $configPath = $basePath . '/config/laravels.php';
285
        $todoList = [
286
            [
287
                'from' => realpath(__DIR__ . '/../../config/laravels.php'),
288
                'to'   => $configPath,
289
                'mode' => 0644,
290
            ],
291
            [
292
                'from' => realpath(__DIR__ . '/../../bin/laravels'),
293
                'to'   => $basePath . '/bin/laravels',
294
                'mode' => 0755,
295
                'link' => true,
296
            ],
297
            [
298
                'from' => realpath(__DIR__ . '/../../bin/fswatch'),
299
                'to'   => $basePath . '/bin/fswatch',
300
                'mode' => 0755,
301
                'link' => true,
302
            ],
303
            [
304
                'from' => realpath(__DIR__ . '/../../bin/inotify'),
305
                'to'   => $basePath . '/bin/inotify',
306
                'mode' => 0755,
307
                'link' => true,
308
            ],
309
        ];
310
        if (file_exists($configPath)) {
311
            $choice = $this->anticipate($configPath . ' already exists, do you want to override it ? Y/N',
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
312
                ['Y', 'N'],
313
                'N'
314
            );
315
            if (!$choice || strtoupper($choice) !== 'Y') {
316
                array_shift($todoList);
317
            }
318
        }
319
320
        foreach ($todoList as $todo) {
321
            $toDir = dirname($todo['to']);
322
            if (!is_dir($toDir) && !mkdir($toDir, 0755, true) && !is_dir($toDir)) {
323
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $toDir));
324
            }
325
            if (file_exists($todo['to'])) {
326
                unlink($todo['to']);
327
            }
328
            $operation = 'Copied';
329
            if (empty($todo['link'])) {
330
                copy($todo['from'], $todo['to']);
331
            } elseif (@link($todo['from'], $todo['to'])) {
332
                $operation = 'Linked';
333
            } else {
334
                copy($todo['from'], $todo['to']);
335
            }
336
            chmod($todo['to'], $todo['mode']);
337
            $this->line("<info>{$operation} file</info> <comment>[{$todo['from']}]</comment> <info>To</info> <comment>[{$todo['to']}]</comment>");
338
        }
339
        return 0;
340
    }
341
}
342