Nginx::findEtcDir()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
ccs 0
cts 9
cp 0
crap 12
1
<?php
2
/**
3
 * HiDev plugin for NGINX
4
 *
5
 * @link      https://github.com/hiqdev/hidev-nginx
6
 * @package   hidev-nginx
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2016-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hidev\nginx\components;
12
13
use Exception;
14
use hidev\base\File;
15
use hidev\modifiers\Sudo;
16
use Yii;
17
use yii\base\InvalidArgumentException;
18
19
/**
20
 * nginx component.
21
 */
22
class Nginx extends \hidev\base\Component
23
{
24
    use \hiqdev\yii2\collection\ManagerTrait;
25
26
    protected $_logDir;
27
    protected $_etcDir;
28
    protected $_fpmSocket;
29
30
    public $defaultClass = Vhost::class;
31
32
    public function dump()
33
    {
34
        foreach ($this->getItems() as $vhost) {
35
            $conf = $vhost->renderConf();
36
            File::plain($vhost->getDomain() . '.conf')->save($conf);
37
        }
38
    }
39
40
    public function deploy()
41
    {
42
        $etcDir = $this->getEtcDir();
43
        if (!is_dir($etcDir)) {
44
            throw new InvalidArgumentException("Non existing Nginx etcDir: $etcDir");
45
        }
46
        $enabledDir   = $etcDir . DIRECTORY_SEPARATOR . 'sites-enabled';
47
        $availableDir = $etcDir . DIRECTORY_SEPARATOR . 'sites-available';
48
        static::mkdir($enabledDir);
49
        static::mkdir($availableDir);
50
        foreach ($this->getItems() as $vhost) {
51
            $conf = $vhost->renderConf();
52
            if (!$vhost->getDomain()) {
53
                Yii::warning('no domain name to put config');
54
                continue;
55
            }
56
            $name = $vhost->getDomain() . '.conf';
57
            $file = File::plain($availableDir . DIRECTORY_SEPARATOR . $name);
58
            $file->save($conf);
59
            $file->symlink($enabledDir . DIRECTORY_SEPARATOR . $name);
60
        }
61
        $this->reload();
62
    }
63
64
    public function start()
65
    {
66
        return $this->run('start');
67
    }
68
69
    public function stop()
70
    {
71
        return $this->run('stop');
72
    }
73
74
    public function Reload()
75
    {
76
        return $this->run('reload');
77
    }
78
79
    public function Restart()
80
    {
81
        return $this->run('restart');
82
    }
83
84
    public function Status()
85
    {
86
        return $this->run('status', false);
87
    }
88
89
    public function run($operation, $sudo = true)
90
    {
91
        $args = ['nginx', $operation];
92
        if ($sudo) {
93
            array_push($args, Sudo::create());
94
        }
95
96
        return $this->passthru('service', $args);
97
    }
98
99
    public function letsencrypt()
100
    {
101
        foreach ($this->getItems() as $vhost) {
102
            $domain = $vhost->getDomain();
103
            $sslDir = $vhost->getSslDir();
104
            $args = ['certonly', '-a', 'webroot', '--webroot-path=' . $vhost->getWebDir()];
105
            foreach (array_reverse($vhost->getDomains()) as $name) {
106
                array_push($args, '-d');
107
                array_push($args, $name);
108
            }
109
            if ($this->passthru('certbot-auto', $args)) {
110
                throw new Exception('failed letsencrypt');
111
            }
112
            static::mkdir($sslDir);
113
            $this->passthru('sh', ['-c', "cp /etc/letsencrypt/live/$domain/* $sslDir", Sudo::create()]);
114
            $vhost->chmodSSL();
115
        }
116
    }
117
118
    public function chmodSSL()
119
    {
120
        foreach ($this->getItems() as $vhost) {
121
            $vhost->chmodSSL();
122
        }
123
    }
124
125
    private static function mkdir($path)
126
    {
127
        if (file_exists($path)) {
128
            return true;
129
        }
130
131
        return mkdir($path, 0777, true);
132
    }
133
134
    /**
135
     * Prepares item config.
136
     */
137
    public function getItemConfig($name = null, array $config = [])
138
    {
139
        return array_merge([
140
            'domain' => $name,
141
            'nginx'  => $this,
142
            'class'  => $this->defaultClass,
143
        ], $config);
144
    }
145
146
    public function createItem($id, $config = [])
147
    {
148
        return Yii::createObject($this->getItemConfig($id, $config));
149
    }
150
151
    public function setLogDir($value)
152
    {
153
        $this->_logDir = $value;
154
    }
155
156
    public function getLogDir()
157
    {
158
        if ($this->_logDir === null) {
159
            $this->_logDir = '/var/log/nginx';
160
        }
161
162
        return $this->_logDir;
163
    }
164
165
    public function setEtcDir($value)
166
    {
167
        $this->_etcDir = $value;
168
    }
169
170
    public function getEtcDir()
171
    {
172
        if ($this->_etcDir === null) {
173
            $this->_etcDir = $this->findEtcDir();
174
        }
175
176
        return $this->_etcDir;
177
    }
178
179
    public function findEtcDir()
180
    {
181
        $dirs = ['/etc/nginx', '/usr/local/etc/nginx'];
182
        foreach ($dirs as $dir) {
183
            if (is_dir($dir)) {
184
                return $dir;
185
            }
186
        }
187
188
        return reset($dirs);
189
    }
190
191
    public function setFpmSocket($value)
192
    {
193
        $this->_fpmSocket = $value;
194
    }
195
196
    public function getFpmSocket()
197
    {
198
        if ($this->_fpmSocket === null) {
199
            $this->_fpmSocket = 'unix:' . $this->findFpmSocketFile();
200
        }
201
202
        return $this->_fpmSocket;
203
    }
204
205
    public function findFpmSocketFile()
206
    {
207
        $files = [
208
            '/run/php/php7.2-fpm.sock',
209
            '/run/php/php7.1-fpm.sock',
210
            '/run/php/php7.0-fpm.sock',
211
            '/var/run/php5-fpm.sock',
212
            '/tmp/php-fpm.sock',
213
        ];
214
        foreach ($files as $file) {
215
            if (file_exists($file)) {
216
                return $file;
217
            }
218
        }
219
220
        return reset($files);
221
    }
222
}
223