Completed
Push — master ( 38192e...3b3b09 )
by Joschi
04:50
created

VirtualHostService::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * admin
5
 *
6
 * @category    Tollwerk
7
 * @package     Tollwerk\Admin
8
 * @subpackage  Tollwerk\Admin\Application\Service
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Tollwerk\Admin\Application\Service;
38
39
use Tollwerk\Admin\Domain\Account\AccountInterface;
40
use Tollwerk\Admin\Domain\Domain\DomainInterface;
41
use Tollwerk\Admin\Domain\Vhost\Vhost;
42
use Tollwerk\Admin\Domain\Vhost\VhostInterface;
43
use Tollwerk\Admin\Infrastructure\Service\DirectoryService;
44
45
/**
46
 * Virtual host service
47
 *
48
 * @package Tollwerk\Admin
49
 * @subpackage Tollwerk\Admin\Application
50
 */
51
class VirtualHostService extends AbstractService
52
{
53
    /**
54
     * Create a virtual host
55
     *
56
     * @param AccountInterface $account Account
57
     * @param DomainInterface $domain Domain
58
     * @param string $docroot Document root
59
     * @param string $type Virtual host Type
60
     * @return VhostInterface Virtual host
61
     */
62
    public function create(
63
        AccountInterface $account,
64
        DomainInterface $domain,
65
        $docroot = '',
66
        $type = Vhost::TYPE_APACHE
67
    ) {
68
        $vhost = $this->storageAdapterStrategy->createVhost(
69
            $account,
70
            $domain,
71
            $this->validateDocroot($account, $docroot),
72
            $type
73
        );
74
        $this->persistenceService->createVhost($account, $vhost);
75
        return $vhost;
76
    }
77
78
    /**
79
     * Load a virtual host
80
     *
81
     * @param AccountInterface $account Account
82
     * @param string $docroot Document root
83
     * @return VhostInterface Virtual host
84
     */
85
    public function load(AccountInterface $account, $docroot = '')
86
    {
87
        return $this->storageAdapterStrategy->loadVhost($account, $this->validateDocroot($account, $docroot));
88
    }
89
90
    /**
91
     * Delete a virtual host
92
     *
93
     * @param AccountInterface $account Account
94
     * @param string $docroot Document root
95
     * @return VhostInterface Virtual host
96
     */
97
    public function delete(AccountInterface $account, $docroot = '')
98
    {
99
        $vhost = $this->storageAdapterStrategy->deleteVhost($account, $this->validateDocroot($account, $docroot));
100
        $this->persistenceService->deleteVhost($account, $vhost);
101
        return $vhost;
102
    }
103
104
    /**
105
     * Enable a virtual host
106
     *
107
     * @param AccountInterface $account Account
108
     * @param string $docroot Document root
109
     * @return VhostInterface Virtual host
110
     */
111
    public function enable(AccountInterface $account, $docroot = '')
112
    {
113
        $vhost = $this->storageAdapterStrategy->enableVhost($account, $this->validateDocroot($account, $docroot));
114
        $this->persistenceService->enableVhost($account, $vhost);
115
        return $vhost;
116
    }
117
118
    /**
119
     * Disable a virtual host
120
     *
121
     * @param AccountInterface $account Account
122
     * @param string $docroot Document root
123
     * @return VhostInterface Virtual host
124
     */
125
    public function disable(AccountInterface $account, $docroot = '')
126
    {
127
        $vhost = $this->storageAdapterStrategy->disableVhost($account, $this->validateDocroot($account, $docroot));
128
        $this->persistenceService->disableVhost($account, $vhost);
129
        return $vhost;
130
    }
131
132
    /**
133
     * Redirect a virtual host
134
     *
135
     * @param string $account Account name
136
     * @param string $docroot Document root
137
     * @param string $url Redirect URL
138
     * @param int $status Redirect HTTP status
139
     * @return VhostInterface Virtual host
140
     * @throws \RuntimeException If the redirect URL is invalid
141
     * @throws \RuntimeException If the redirect HTTP status code is invalid
142
     */
143
    public function redirect(
144
        AccountInterface $account,
145
        $docroot = '',
146
        $url = '',
147
        $status = Vhost::REDIRECT_DEFAULT_STATUS
148
    ) {
149
        $url = trim($url) ?: null;
150
151
        // If the redirect URL is invalid
152
        if (($url !== null) &&
153
            (!filter_var($url, FILTER_VALIDATE_URL)
154
                || !in_array(strtolower(parse_url($url, PHP_URL_SCHEME)), Vhost::$supportedProtocols))
155
        ) {
156
            throw new \RuntimeException(sprintf('Invalid redirect URL "%s"', $url), 1475486589);
157
        }
158
159
        // If the redirect HTTP status code is invalid
160
        if (!is_int($status) || (($status < 300) || ($status > 308))) {
161
            throw new \RuntimeException(sprintf('Invalid redirect HTTP status code "%s"', $status), 1475486679);
162
        }
163
164
        $vhost = $this->storageAdapterStrategy->redirectVhost(
165
            $account,
166
            $this->validateDocroot($account, $docroot),
167
            $url,
168
            $status
169
        );
170
        $this->persistenceService->redirectVhost($account, $vhost);
171
        return $vhost;
172
    }
173
174
    /**
175
     * Configure the PHP version of a virtual host
176
     *
177
     * @param string $account Account name
178
     * @param string $docroot Document root
179
     * @param string|null $php PHP version
180
     * @return VhostInterface Virtual host
181
     * @throws \RuntimeException If the redirect URL is invalid
182
     * @throws \RuntimeException If the redirect HTTP status code is invalid
183
     */
184
    public function php(AccountInterface $account, $docroot = '', $php = null)
185
    {
186
        $php = trim($php) ?: null;
187
188
        // If the PHP version is invalid
189
        if (($php !== null) && (!preg_match("%^[5789]\.\d$%", $php) || (floatval($php) < 5.6))) {
190
            throw new \RuntimeException(sprintf('Invalid PHP version "%s"', $php), 1475937755);
191
        }
192
193
        // Validate the docroot
194
        $docroot = $this->validateDocroot($account, $docroot);
195
        $oldVhost = $this->load($account, $docroot);
196
197
        $vhost = $this->storageAdapterStrategy->phpVhost($account, $docroot, $php);
198
        $this->persistenceService->phpVhost($account, $vhost, $oldVhost->getPhp());
199
        return $vhost;
200
    }
201
202
    /**
203
     * Configure a protocol based port for a virtual host
204
     *
205
     * @param AccountInterface $account Account
206
     * @param string $docroot Document root
207
     * @param int $protocol Protocol
208
     * @param int|null $port Port
209
     * @return VhostInterface Virtual host
210
     * @throws \RuntimeException If the protocol is invalid
211
     * @throws \RuntimeException If the protocol port is invalid
212
     */
213
    public function port(
214
        AccountInterface $account,
215
        $docroot = '',
216
        $protocol = \Tollwerk\Admin\Domain\Vhost\Vhost::PROTOCOL_HTTP,
217
        $port = null
218
    ) {
219
        // If the protocol is unsupported
220
        if (empty(Vhost::$supportedProtocols[$protocol])) {
221
            throw new \RuntimeException(sprintf('Invalid protocol "%s"', $protocol), 1475484081);
222
        }
223
224
        // If the protocol port is invalid
225
        $port = ($port === null) ? Vhost::$defaultProtocolPorts[$protocol] : (intval($port) ?: null);
226
        if (($port !== null) && ($port <= 0)) {
227
            throw new \RuntimeException(sprintf('Invalid protocol port "%s"', $port), 1475502412);
228
        }
229
230
        $vhost = $this->storageAdapterStrategy->portVhost(
231
            $account,
232
            $this->validateDocroot($account, $docroot),
233
            $protocol,
234
            $port
235
        );
236
        $this->persistenceService->portVhost($account, $vhost);
237
        return $vhost;
238
    }
239
240
    /**
241
     * Add a secondary domain to a virtual host
242
     *
243
     * @param string $account Account name
244
     * @param DomainInterface $domain Domain
245
     * @param string $docroot Document root
246
     * @return VhostInterface Virtual host
247
     */
248
    public function addDomain(AccountInterface $account, DomainInterface $domain, $docroot = '')
249
    {
250
        $vhost = $this->storageAdapterStrategy->addVhostDomain(
251
            $account,
252
            $this->validateDocroot($account, $docroot),
253
            $domain
254
        );
255
        $this->persistenceService->domainVhost($account, $vhost);
256
        return $vhost;
257
    }
258
259
    /**
260
     * Remove a secondary domain from a virtual host
261
     *
262
     * @param string $account Account name
263
     * @param DomainInterface $domain Domain
264
     * @param string $docroot Document root
265
     * @return VhostInterface Virtual host
266
     */
267
    public function removeDomain(AccountInterface $account, DomainInterface $domain, $docroot = '')
268
    {
269
        $vhost = $this->storageAdapterStrategy->removeVhostDomain(
270
            $account,
271
            $this->validateDocroot($account, $docroot),
272
            $domain
273
        );
274
        $this->persistenceService->domainVhost($account, $vhost);
275
        return $vhost;
276
    }
277
278
    /**
279
     * Validate a given document root path
280
     *
281
     * @param AccountInterface $account Account
282
     * @param string $docroot Document root
283
     * @return string Validated document root
284
     */
285
    protected function validateDocroot(AccountInterface $account, $docroot)
286
    {
287
        $accountDirectorySvc = new DirectoryService($account);
288
        return $accountDirectorySvc->getDataDirectory($docroot, false);
289
    }
290
}
291