Completed
Push — master ( f89fcb...8019b6 )
by Biao
03:13
created

LaravelSCommand::preSet()   F

Complexity

Conditions 11
Paths 576

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 21
nc 576
nop 1
dl 0
loc 31
rs 3.7388
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Hhxsv5\LaravelS\Illuminate;
4
5
use Illuminate\Console\Command;
6
7
class LaravelSCommand extends Command
8
{
9
    protected $signature = 'laravels {action? : publish|config|info}
10
    {--d|daemonize : Whether run as a daemon for "start & restart"}
11
    {--i|ignore : Whether ignore checking process pid for "start & restart"}';
12
13
    protected $description = 'LaravelS console tool';
14
15
    public function fire()
16
    {
17
        $this->handle();
18
    }
19
20
    public function handle()
21
    {
22
        $action = (string)$this->argument('action');
23
        switch ($action) {
24
            case 'publish':
25
                $this->publish();
26
                break;
27
            case 'config':
28
                $this->prepareConfig();
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment if this fall-through is intended.
Loading history...
29
            case 'info':
30
                $this->showInfo();
31
                break;
32
            default:
33
                $this->info(sprintf('Usage: [%s] ./artisan laravels publish|config|info', PHP_BINARY));
34
                if (in_array($action, ['start', 'stop', 'restart', 'reload'], true)) {
35
                    $this->error(sprintf(
36
                        'The "%s" command has been migrated to "bin/laravels", %ssee https://github.com/hhxsv5/laravel-s#run',
37
                        $action,
38
                        file_exists(base_path('bin/laravels')) ? '' : 'please run `php artisan laravels publish` first, '
39
                    ));
40
                }
41
                break;
42
        }
43
    }
44
45
    protected function isLumen()
46
    {
47
        return stripos($this->getApplication()->getVersion(), 'Lumen') !== false;
48
    }
49
50
    protected function loadConfig()
51
    {
52
        // Load configuration laravel.php manually for Lumen
53
        $basePath = config('laravels.laravel_base_path') ?: base_path();
54
        if ($this->isLumen() && file_exists($basePath . '/config/laravels.php')) {
55
            $this->getLaravel()->configure('laravels');
0 ignored issues
show
Bug introduced by
The method configure() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

55
            $this->getLaravel()->/** @scrutinizer ignore-call */ configure('laravels');

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
        }
57
    }
58
59
    protected function showInfo()
60
    {
61
        $this->showLogo();
62
        $this->showComponents();
63
        $this->showDashboard();
64
    }
65
66
    protected function showLogo()
67
    {
68
        static $logo = <<<EOS
69
 _                               _  _____ 
70
| |                             | |/ ____|
71
| |     __ _ _ __ __ ___   _____| | (___  
72
| |    / _` | '__/ _` \ \ / / _ \ |\___ \ 
73
| |___| (_| | | | (_| |\ V /  __/ |____) |
74
|______\__,_|_|  \__,_| \_/ \___|_|_____/ 
75
                                           
76
EOS;
77
        $this->info($logo);
78
        $this->info('Speed up your Laravel/Lumen');
79
    }
80
81
    protected function showComponents()
82
    {
83
        $this->comment('>>> Components');
84
        $laravelSVersion = '-';
85
        $cfg = (array)json_decode(file_get_contents(base_path('composer.lock')), true);
86
        if (isset($cfg['packages'])) {
87
            $packages = array_merge($cfg['packages'], array_get($cfg, 'packages-dev', []));
88
            foreach ($packages as $package) {
89
                if (isset($package['name']) && $package['name'] === 'hhxsv5/laravel-s') {
90
                    $laravelSVersion = ltrim($package['version'], 'vV');
91
                    break;
92
                }
93
            }
94
        }
95
        $this->table(['Component', 'Version'], [
96
            [
97
                'PHP',
98
                phpversion(),
99
            ],
100
            [
101
                'Swoole',
102
                swoole_version(),
103
            ],
104
            [
105
                'LaravelS',
106
                $laravelSVersion,
107
            ],
108
            [
109
                $this->getApplication()->getName() . ' [<info>' . env('APP_ENV') . '</info>]',
110
                $this->getApplication()->getVersion(),
111
            ],
112
        ]);
113
    }
114
115
    protected function showDashboard()
116
    {
117
        $this->comment('>>> Dashboard');
118
119
        $config = (array)json_decode(file_get_contents(base_path('storage/laravels.json')), true);
120
        $socketType = isset($config['server']['socket_type']) ? $config['server']['socket_type'] : SWOOLE_SOCK_TCP;
121
        if (in_array($socketType, [SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_UNIX_STREAM])) {
122
            $listenAt = $config['server']['listen_ip'];
123
        } else {
124
            $listenAt = sprintf('%s:%s', $config['server']['listen_ip'], $config['server']['listen_port']);
125
        }
126
127
        $tableRows = [
128
            [
129
                'Main HTTP',
130
                '<info>On</info>',
131
                $this->getApplication()->getName(),
132
                $listenAt,
133
            ],
134
        ];
135
        if (!empty($config['server']['websocket']['enable'])) {
136
            $tableRows [] = [
137
                'Main WebSocket',
138
                '<info>On</info>',
139
                $config['server']['websocket']['handler'],
140
                $listenAt,
141
            ];
142
        }
143
144
        $socketTypeNames = [
145
            SWOOLE_SOCK_TCP         => 'TCP IPV4 Socket',
146
            SWOOLE_SOCK_TCP6        => 'TCP IPV6 Socket',
147
            SWOOLE_SOCK_UDP         => 'UDP IPV4 Socket',
148
            SWOOLE_SOCK_UDP6        => 'TCP IPV6 Socket',
149
            SWOOLE_SOCK_UNIX_DGRAM  => 'Unix Socket Dgram',
150
            SWOOLE_SOCK_UNIX_STREAM => 'Unix Socket Stream',
151
        ];
152
        $sockets = isset($config['server']['sockets']) ? $config['server']['sockets'] : [];
153
        foreach ($sockets as $key => $socket) {
154
            $name = 'Port#' . $key . ' ';
155
            $name .= isset($socketTypeNames[$socket['type']]) ? $socketTypeNames[$socket['type']] : 'Unknown socket';
156
            $tableRows [] = [
157
                $name,
158
                '<info>On</info>',
159
                $socket['handler'],
160
                sprintf('%s:%s', $socket['host'], $socket['port']),
161
            ];
162
        }
163
        $this->table(['Protocol', 'Status', 'Handler', 'Listen At'], $tableRows);
164
165
        $this->comment('>>> Feedback: <options=underscore>https://github.com/hhxsv5/laravel-s</>');
166
    }
167
168
    protected function prepareConfig()
169
    {
170
        $this->loadConfig();
171
172
        $svrConf = config('laravels');
173
174
        $this->preSet($svrConf);
175
176
        $ret = $this->preCheck($svrConf);
177
        if ($ret !== 0) {
178
            return $ret;
179
        }
180
181
        $laravelConf = [
182
            'root_path'          => $svrConf['laravel_base_path'],
183
            'static_path'        => $svrConf['swoole']['document_root'],
184
            'register_providers' => array_unique((array)array_get($svrConf, 'register_providers', [])),
185
            'is_lumen'           => $this->isLumen(),
186
            '_SERVER'            => $_SERVER,
187
            '_ENV'               => $_ENV,
188
        ];
189
190
        $config = ['server' => $svrConf, 'laravel' => $laravelConf];
191
        $jsonConfig = json_encode($config, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
192
        return file_put_contents(base_path('storage/laravels.json'), $jsonConfig) > 0 ? 0 : 1;
193
    }
194
195
    protected function preSet(array &$svrConf)
196
    {
197
        if (!isset($svrConf['enable_gzip'])) {
198
            $svrConf['enable_gzip'] = false;
199
        }
200
        if (empty($svrConf['laravel_base_path'])) {
201
            $svrConf['laravel_base_path'] = base_path();
202
        }
203
        if (empty($svrConf['process_prefix'])) {
204
            $svrConf['process_prefix'] = $svrConf['laravel_base_path'];
205
        }
206
        if ($this->option('ignore')) {
207
            $svrConf['ignore_check_pid'] = true;
208
        } elseif (!isset($svrConf['ignore_check_pid'])) {
209
            $svrConf['ignore_check_pid'] = false;
210
        }
211
        if (empty($svrConf['swoole']['document_root'])) {
212
            $svrConf['swoole']['document_root'] = $svrConf['laravel_base_path'] . '/public';
213
        }
214
        if ($this->option('daemonize')) {
215
            $svrConf['swoole']['daemonize'] = true;
216
        } elseif (!isset($svrConf['swoole']['daemonize'])) {
217
            $svrConf['swoole']['daemonize'] = false;
218
        }
219
        if (empty($svrConf['swoole']['pid_file'])) {
220
            $svrConf['swoole']['pid_file'] = storage_path('laravels.pid');
221
        }
222
        if (empty($svrConf['timer']['pid_file'])) {
223
            $svrConf['timer']['pid_file'] = storage_path('laravels-timer.pid');
224
        }
225
        return 0;
226
    }
227
228
    protected function preCheck(array $svrConf)
229
    {
230
        if (!empty($svrConf['enable_gzip']) && version_compare(swoole_version(), '4.1.0', '>=')) {
231
            $this->error('enable_gzip is DEPRECATED since Swoole 4.1.0, set http_compression of Swoole instead, http_compression is disabled by default.');
232
            $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.');
233
            return 1;
234
        }
235
        if (!empty($svrConf['events'])) {
236
            if (empty($svrConf['swoole']['task_worker_num']) || $svrConf['swoole']['task_worker_num'] <= 0) {
237
                $this->error('Asynchronous event listening needs to set task_worker_num > 0');
238
                return 1;
239
            }
240
        }
241
        return 0;
242
    }
243
244
245
    public function publish()
246
    {
247
        $basePath = config('laravels.laravel_base_path') ?: base_path();
248
        $configPath = $basePath . '/config/laravels.php';
249
        $todoList = [
250
            [
251
                'from' => realpath(__DIR__ . '/../../config/laravels.php'),
252
                'to'   => $configPath,
253
                'mode' => 0644,
254
            ],
255
            [
256
                'from' => realpath(__DIR__ . '/../../bin/laravels'),
257
                'to'   => $basePath . '/bin/laravels',
258
                'mode' => 0755,
259
                'link' => true,
260
            ],
261
            [
262
                'from' => realpath(__DIR__ . '/../../bin/fswatch'),
263
                'to'   => $basePath . '/bin/fswatch',
264
                'mode' => 0755,
265
                'link' => true,
266
            ],
267
        ];
268
        if (file_exists($configPath)) {
269
            $choice = $this->anticipate($configPath . ' already exists, do you want to override it ? Y/N',
270
                ['Y', 'N'],
271
                'N'
272
            );
273
            if (!$choice || strtoupper($choice) !== 'Y') {
274
                array_shift($todoList);
275
            }
276
        }
277
278
        foreach ($todoList as $todo) {
279
            $toDir = dirname($todo['to']);
280
            if (!is_dir($toDir)) {
281
                mkdir($toDir, 0755, true);
282
            }
283
            if (file_exists($todo['to'])) {
284
                unlink($todo['to']);
285
            }
286
            $operation = 'Copied';
287
            if (empty($todo['link'])) {
288
                copy($todo['from'], $todo['to']);
289
            } else {
290
                if (@link($todo['from'], $todo['to'])) {
291
                    $operation = 'Linked';
292
                } else {
293
                    copy($todo['from'], $todo['to']);
294
                }
295
296
            }
297
            chmod($todo['to'], $todo['mode']);
298
            $this->line("<info>{$operation} file</info> <comment>[{$todo['from']}]</comment> <info>To</info> <comment>[{$todo['to']}]</comment>");
299
        }
300
        return 0;
301
    }
302
}
303