Passed
Pull Request — master (#225)
by Dmitriy
02:30
created

DebugServerCommand   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 72
rs 10
c 0
b 0
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A execute() 0 47 5
A configure() 0 9 1
A __construct() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
declare(ticks=1);
5
6
namespace Yiisoft\Yii\Debug\Command;
7
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Console\Style\SymfonyStyle;
13
use Yiisoft\Yii\Console\ExitCode;
14
use Yiisoft\Yii\Debug\DebugServer\Connection;
15
16
final class DebugServerCommand extends Command
17
{
18
    public const COMMAND_NAME = 'dev';
19
    protected static $defaultName = self::COMMAND_NAME;
20
21
    protected static $defaultDescription = 'Runs PHP built-in web server';
22
23
    public function __construct(
24
        private string $address = '0.0.0.0',
25
        private int $port = 8890,
26
    ) {
27
        parent::__construct();
28
    }
29
30
    public function configure(): void
31
    {
32
        $this
33
            ->setHelp(
34
                'In order to access server from remote machines use 0.0.0.0:8000. That is especially useful when running server in a virtual machine.'
35
            )
36
            ->addOption('address', 'a', InputOption::VALUE_OPTIONAL, 'Host to serve at', $this->address)
37
            ->addOption('port', 'p', InputOption::VALUE_OPTIONAL, 'Port to serve at', $this->port)
38
            ->addOption('env', 'e', InputOption::VALUE_OPTIONAL, 'It is only used for testing.');
39
    }
40
41
    protected function execute(InputInterface $input, OutputInterface $output): int
42
    {
43
        $io = new SymfonyStyle($input, $output);
44
        $io->title('Yii3 Debug Server');
45
        $io->writeln('https://yiiframework.com' . "\n");
46
47
        $env = $input->getOption('env');
48
        if ($env === 'test') {
49
            return ExitCode::OK;
50
        }
51
52
        $socket = Connection::create();
53
        $socket->bind();
54
55
        $io->success(
56
            sprintf(
57
                'Listening on "%s".',
58
                $socket->getUri(),
59
            )
60
        );
61
62
        if (\function_exists('pcntl_signal')) {
63
            $io->success('Quit the server with CTRL-C or COMMAND-C.');
64
65
            \pcntl_signal(\SIGINT, static function () use ($socket): void {
66
                $socket->close();
67
                exit(1);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
68
            });
69
        }
70
71
        foreach ($socket->read() as $message) {
72
            if ($message[0] === Connection::TYPE_ERROR) {
73
                $io->error('Connection closed with error: ' . $message[1]);
74
                break;
75
            }
76
77
            $data = \json_decode($message[1], null, 512, JSON_THROW_ON_ERROR);
78
            $type = match ($data[0]) {
79
                Connection::MESSAGE_TYPE_VAR_DUMPER => 'VarDumper',
80
                Connection::MESSAGE_TYPE_LOGGER => 'Logger',
81
                default => 'Plain text',
82
            };
83
84
            $io->block($data[1], $type);
85
        }
86
87
        return ExitCode::OK;
88
    }
89
}
90