Passed
Push — master ( 3ee5ba...23bbf0 )
by Keoghan
04:26
created

Site::resolveFromPathOrCurrentWorkingDirectory()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 1
crap 3
1
<?php
2
3
namespace App\Models;
4
5
use App\Porter;
6
use App\PorterLibrary;
7
use App\Support\Contracts\Cli;
8
use App\Support\Nginx\SiteConfBuilder;
9
use App\Support\Ssl\CertificateBuilder;
10
use Illuminate\Database\Eloquent\Model;
11
12
class Site extends Model
13
{
14
    protected $guarded = [];
15
    protected $casts = ['secure' => 'boolean'];
16
17
    /**
18
     * PHP Version.
19
     *
20
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
21
     */
22 4
    public function php_version()
23
    {
24 4
        return $this->belongsTo(PhpVersion::class);
25
    }
26
27
    /**
28
     * Resolve the site from the current working directory.
29
     *
30
     * @param string|null $path
31
     *
32
     * @return Site|null
33
     */
34 9
    public static function resolveFromPathOrCurrentWorkingDirectory($path = null)
35
    {
36 9
        $name = static::nameFromPath($path ?: app(Cli::class)->currentWorkingDirectory());
37
38 9
        if (!$name) {
39 1
            return;
40
        }
41
42 8
        return static::where('name', $name)->first();
43
    }
44
45
    /**
46
     * Resolve the site from the current working directory
47
     * Fail if not found.
48
     *
49
     * @param string|null $path
50
     *
51
     * @throws \Exception
52
     *
53
     * @return Site|null
54
     */
55 1
    public static function resolveFromPathOrCurrentWorkingDirectoryOrFail($path = null)
56
    {
57 1
        $site = static::resolveFromPathOrCurrentWorkingDirectory($path);
58
59 1
        if (!$site) {
60 1
            throw new \Exception('Site not found.');
61
        }
62
63 1
        return $site;
64
    }
65
66
    /**
67
     * Get the url for this site.
68
     *
69
     * @return string
70
     */
71 10
    public function getUrlAttribute()
72
    {
73 10
        return $this->name.'.'.setting('domain');
74
    }
75
76
    /**
77
     * Get the scheme for this site.
78
     *
79
     * @return string
80
     */
81 1
    public function getSchemeAttribute()
82
    {
83 1
        return ($this->secure ? 'https' : 'http').'://';
84
    }
85
86
    /**
87
     * Return the path for the NGiNX config file.
88
     *
89
     * @return string
90
     */
91 3
    public function getNginxConfPathAttribute()
92
    {
93 3
        return $this->getPorterLibrary()->configPath()."/nginx/conf.d/{$this->name}.conf";
94
    }
95
96
    /**
97
     * Return the full NGiNX template to use.
98
     *
99
     * @return string
100
     */
101 3
    public function getNginxConfTemplateAttribute()
102
    {
103 3
        $type = $this->nginx_conf ?? 'default';
104
105 3
        return "nginx.{$type}.domain".(($this->secure ?? false) ? '_secure' : '');
106
    }
107
108
    /**
109
     * Build the files for this site (e.g. nginx conf).
110
     *
111
     * @throws \Throwable
112
     */
113 9
    public function buildFiles()
114
    {
115 9
        $this->getSiteConfigBuilder()->build($this);
116 9
    }
117
118
    /**
119
     * Destroy the files for this site (e.g. NGiNX conf).
120
     */
121 1
    public function destroyFiles()
122
    {
123 1
        $this->getSiteConfigBuilder()->destroy($this);
124 1
    }
125
126
    /**
127
     * Secure the site. Build certs.
128
     */
129 2
    public function secure()
130
    {
131 2
        $this->buildCertificate();
132
133 2
        $this->update(['secure' => true]);
134
135 2
        $this->buildFiles();
136
137 2
        $this->getPorter()->restartServing();
138 2
    }
139
140
    /**
141
     * Unsecure this site.
142
     */
143 2
    public function unsecure()
144
    {
145 2
        $this->destroyCertificate();
146
147 2
        $this->update(['secure' => false]);
148
149 2
        $this->buildFiles();
150
151 2
        $this->getPorter()->restartServing();
152 2
    }
153
154
    /**
155
     * Remove this site and associated files.
156
     *
157
     * @throws \Exception
158
     * @throws \Throwable
159
     */
160 1
    public function remove()
161
    {
162 1
        $this->destroyCertificate();
163
164 1
        $this->getSiteConfigBuilder()->destroy($this);
165
166 1
        $this->delete();
167
168 1
        $this->getPorter()->restartServing();
169 1
    }
170
171
    /**
172
     * Set the PHP version for the site.
173
     *
174
     * @param int|null $phpVersionId
175
     *
176
     * @throws \Throwable
177
     */
178 2
    public function setPhpVersion($phpVersionId = null)
179
    {
180 2
        $this->update(['php_version_id' => $phpVersionId ?: PhpVersion::defaultVersion()->id]);
181
182
        // The php_version relation needs to be refreshed, so get a whole new representation of this
183 2
        $this->refresh();
184
185 2
        $this->buildFiles();
186
187 2
        $this->getPorter()->restartServing();
188 2
    }
189
190
    /**
191
     * Set the nginx type for the site (we have different template configs we can use).
192
     *
193
     * @param $type
194
     *
195
     * @throws \Throwable
196
     */
197 1
    public function setNginxType($type)
198
    {
199 1
        $this->update(['nginx_conf' => $type ?? 'default']);
200
201 1
        $this->buildFiles();
202
203 1
        $this->getPorter()->restartServing();
204 1
    }
205
206
    /**
207
     * Get the first site based on name, or create a new record.
208
     *
209
     *
210
     * @param $name
211
     *
212
     * @return mixed
213
     */
214 1
    public static function firstOrCreateForName($name)
215
    {
216 1
        $result = static::where('name', $name)->first();
217
218 1
        if ($result) {
219 1
            return $result;
220
        }
221
222 1
        return static::createForName($name);
223
    }
224
225
    /**
226
     * Create an new site based on the name.
227
     *
228
     * @param $name
229
     *
230
     * @return mixed
231
     */
232 2
    public static function createForName($name)
233
    {
234 2
        return static::create([
235 2
            'name'           => $name,
236 2
            'nginx_conf'     => 'default',
237 2
            'php_version_id' => PhpVersion::defaultVersion()->id,
238
            'secure'         => false,
239
        ]);
240
    }
241
242
    /**
243
     * Get Certificate builder.
244
     *
245
     * @return CertificateBuilder
246
     */
247 7
    protected function getCertificateBuilder()
248
    {
249 7
        return app(CertificateBuilder::class);
250
    }
251
252
    /**
253
     * Get Site Config Builder.
254
     *
255
     * @return \App\Support\Nginx\SiteConfBuilder
256
     */
257 11
    protected function getSiteConfigBuilder()
258
    {
259 11
        return app(SiteConfBuilder::class);
260
    }
261
262
    /**
263
     * Get Porter.
264
     *
265
     * @return Porter
266
     */
267 7
    protected function getPorter()
268
    {
269 7
        return app(Porter::class);
270
    }
271
272
    /**
273
     * Get PorterLibrary.
274
     *
275
     * @return PorterLibrary
276
     */
277 3
    protected function getPorterLibrary()
278
    {
279 3
        return app(PorterLibrary::class);
280
    }
281
282
    /**
283
     * Build Certificate for site.
284
     */
285 4
    public function buildCertificate()
286
    {
287 4
        $this->getCertificateBuilder()->build($this->url);
288 4
    }
289
290
    /**
291
     * Destroy Certificate for site.
292
     */
293 4
    public function destroyCertificate()
294
    {
295 4
        $this->getCertificateBuilder()->destroy($this->url);
296 4
    }
297
298
    /**
299
     * Return a site directory name from a path, after checking it is within the
300
     * home directory.
301
     *
302
     * @param $path
303
     *
304
     * @return null|string
305
     */
306 13
    public static function nameFromPath($path)
307
    {
308 13
        $home = setting('home');
309
310 13
        if (strpos($path, DIRECTORY_SEPARATOR) === false) {
311 5
            return $path;
312
        }
313
314 8
        if (strpos($path, $home) !== 0) {
315 2
            return;
316
        }
317
318 6
        $path = trim(str_after($path, $home), DIRECTORY_SEPARATOR);
319
320 6
        return str_before($path, DIRECTORY_SEPARATOR);
321
    }
322
}
323