Completed
Push — master ( 23ec21...af84c1 )
by Arman
16s queued 13s
created

ServeCommand   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
c 1
b 0
f 0
dl 0
loc 152
rs 10
wmc 16

7 Methods

Rating   Name   Duplication   Size   Complexity  
A exec() 0 12 3
A detectPlatformCommand() 0 11 4
A host() 0 3 2
A portAvailable() 0 9 2
A port() 0 4 2
A openBrowserCommand() 0 9 2
A runServerCommand() 0 3 1
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.7.0
13
 */
14
15
namespace Quantum\Console\Commands;
16
17
use Quantum\Console\QtCommand;
18
19
/**
20
 * Class ServeCommand
21
 * @package Base\Commands
22
 */
23
class ServeCommand extends QtCommand
24
{
25
26
    /**
27
     * Platform Windows
28
     */
29
    const PLATFORM_WINDOWS = 'WINNT';
30
31
    /**
32
     * Platform Linux
33
     */
34
    const PLATFORM_LINUX = 'Linux';
35
36
    /**
37
     * Platform Mac
38
     */
39
    const PLATFORM_MAC = 'Darwin';
40
41
    /**
42
     * The console command name.
43
     * @var string
44
     */
45
    protected $name = 'serve';
46
47
    /**
48
     * The console command description.
49
     * @var string
50
     */
51
    protected $description = 'Serves the application on the PHP development server';
52
53
    /**
54
     * Default host
55
     * @var string
56
     */
57
    protected $defaultHost = '127.0.0.1';
58
59
    /**
60
     * Default port
61
     * @var int
62
     */
63
    protected $defaultPort = 8000;
64
65
    /**
66
     * The current port offset.
67
     * @var int
68
     */
69
    protected $portOffset = 0;
70
71
    /**
72
     * Command arguments
73
     * @var \string[][]
74
     */
75
    protected $options = [
76
        ['host', null, 'optional', 'Host', '127.0.0.1'],
77
        ['port', null, 'optional', 'Port', '8000'],
78
    ];
79
80
    /**
81
     * Executes the command
82
     * @throws \Quantum\Exceptions\DiException
83
     */
84
    public function exec()
85
    {
86
        if (!$this->portAvailable()) {
87
            $this->portOffset += 1;
88
            $this->exec();
89
        } else {
90
            if (!$this->openBrowserCommand()) {
91
                $this->info('Starting development server at: ' . $this->host() . ':' . $this->port());
92
                exec($this->runServerCommand(), $out);
93
            } else {
94
                $this->info('Starting development server at: ' . $this->host() . ':' . $this->port());
95
                exec($this->openBrowserCommand() . ' && ' . $this->runServerCommand(), $out);
96
            }
97
        }
98
    }
99
100
    /**
101
     * Starts the php development server
102
     * @return string
103
     */
104
    protected function runServerCommand(): string
105
    {
106
        return 'php -S ' . $this->host() . ':' . $this->port() . ' -t public';
107
    }
108
109
    /**
110
     * Tries to open the default browser
111
     * @return string|null
112
     */
113
    protected function openBrowserCommand(): ?string
114
    {
115
        $platformCommand = $this->detectPlatformCommand();
116
117
        if (!$platformCommand) {
118
            return null;
119
        }
120
121
        return $platformCommand . ' http://' . $this->host() . ':' . $this->port();
122
    }
123
124
    /**
125
     * Checks the available port
126
     * @return bool
127
     */
128
    protected function portAvailable(): bool
129
    {
130
        $connection = @fsockopen($this->host(), $this->port(), $errno, $err, 30);
131
132
        if (!is_resource($connection)) {
133
            return true;
134
        } else {
135
            fclose($connection);
136
            return false;
137
        }
138
    }
139
140
    /**
141
     * Detects the platform
142
     * @return string|null
143
     */
144
    protected function detectPlatformCommand(): ?string
145
    {
146
        switch (PHP_OS) {
147
            case self::PLATFORM_LINUX:
148
                return 'xdg-open';
149
            case self::PLATFORM_WINDOWS:
150
                return 'start';
151
            case self::PLATFORM_MAC:
152
                return 'open';
153
            default:
154
                return null;
155
        }
156
    }
157
158
    /**
159
     * Gets the host
160
     * @return mixed|string
161
     */
162
    protected function host()
163
    {
164
        return $this->getOption('host') ?: $this->defaultHost;
165
    }
166
167
    /**
168
     * Gets the port
169
     * @return int|mixed|string
170
     */
171
    protected function port()
172
    {
173
        $port = $this->getOption('port') ?: $this->defaultPort;
174
        return $port + $this->portOffset;
175
    }
176
}
177
178