Completed
Push — master ( 9003f0...ee041c )
by Joschi
04:37
created

DoctrineStorageAdapterStrategy::loadDomain()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 34
c 0
b 0
f 0
ccs 0
cts 19
cp 0
rs 8.439
cc 5
eloc 17
nc 5
nop 2
crap 30
1
<?php
2
3
/**
4
 * admin
5
 *
6
 * @category    Tollwerk
7
 * @package     Tollwerk\Admin
8
 * @subpackage  Tollwerk\Admin\Infrastructure\Strategy
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\Infrastructure\Strategy;
38
39
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
40
use Doctrine\ORM\EntityManager;
41
use Doctrine\ORM\EntityRepository;
42
use Tollwerk\Admin\Application\Contract\StorageAdapterStrategyInterface;
43
use Tollwerk\Admin\Domain\Account\Account;
44
use Tollwerk\Admin\Domain\Account\AccountInterface;
45
use Tollwerk\Admin\Domain\Domain\DomainInterface;
46
use Tollwerk\Admin\Domain\Factory\DomainFactory;
47
use Tollwerk\Admin\Domain\Vhost\Vhost;
48
use Tollwerk\Admin\Infrastructure\App;
49
use Tollwerk\Admin\Infrastructure\Model\Account as DoctrineAccount;
50
use Tollwerk\Admin\Infrastructure\Model\Domain as DoctrineDomain;
51
use Tollwerk\Admin\Infrastructure\Model\Vhost as DoctrineVhost;
52
53
/**
54
 * DoctrineAccountFactoryStrategy
55
 *
56
 * @package Tollwerk\Admin
57
 * @subpackage Tollwerk\Admin\Infrastructure\Strategy
58
 */
59
class DoctrineStorageAdapterStrategy implements StorageAdapterStrategyInterface
60
{
61
    /**
62
     * Doctrine entity manager
63
     *
64
     * @var EntityManager
65
     */
66
    protected $entityManager;
67
    /**
68
     * Account repository
69
     *
70
     * @var EntityRepository
71
     */
72
    protected $accountRepository;
73
    /**
74
     * Domain repository
75
     *
76
     * @var EntityRepository
77
     */
78
    protected $domainRepository;
79
    /**
80
     * Virtual host repository
81
     *
82
     * @var EntityRepository
83
     */
84
    protected $vhostRepository;
85
86
    /**
87
     * Constructor
88
     */
89
    public function __construct()
90
    {
91
        $this->entityManager = App::getEntityManager();
92
        $this->accountRepository =
93
            $this->entityManager->getRepository(\Tollwerk\Admin\Infrastructure\Model\Account::class);
94
        $this->domainRepository =
95
            $this->entityManager->getRepository(\Tollwerk\Admin\Infrastructure\Model\Domain::class);
96
        $this->vhostRepository =
97
            $this->entityManager->getRepository(\Tollwerk\Admin\Infrastructure\Model\Vhost::class);
98
    }
99
100
    /**
101
     * Create an account
102
     *
103
     * @param string $name Account name
104
     * @return AccountInterface Account
105
     * @throws \RuntimeException If the account cannot be created
106
     */
107
    public function createAccount($name)
108
    {
109
        // Create the new account
110
        $doctrineAccount = new DoctrineAccount();
111
        $doctrineAccount->setName($name);
112
        $doctrineAccount->setActive(false);
113
114
        // Persist the new account
115
        try {
116
            $this->entityManager->persist($doctrineAccount);
117
            $this->entityManager->flush();
118
        } catch (UniqueConstraintViolationException $e) {
119
            $doctrineAccount = $this->accountRepository->findOneBy(['name' => $name]);
120
        } catch (\Exception $e) {
121
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
122
        }
123
124
        // Create and return a domain account
125
        $account = new Account($doctrineAccount->getName());
126
        $account->setActive($doctrineAccount->getActive());
127
        return $account;
128
    }
129
130
    /**
131
     * Enable an account
132
     *
133
     * @param string $name Account name
134
     * @return AccountInterface Account
135
     * @throws \RuntimeException If the account cannot be enabled
136
     */
137
    public function enableAccount($name)
138
    {
139
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $name]);
140
141
        // If the account is unknown
142
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
143
            throw new \RuntimeException(sprintf('Unknown account "%s"', $name), 1475495500);
144
        }
145
146
        // Enable and persist the account
147
        try {
148
            $doctrineAccount->setActive(true);
149
            $this->entityManager->persist($doctrineAccount);
150
            $this->entityManager->flush();
151
        } catch (\Exception $e) {
152
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
153
        }
154
155
        return $this->loadFromDoctrineAccount($doctrineAccount);
156
    }
157
158
    /**
159
     * Disable an account
160
     *
161
     * @param string $name Account name
162
     * @return AccountInterface Account
163
     * @throws \RuntimeException If the account cannot be disabled
164
     */
165
    public function disableAccount($name)
166
    {
167
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $name]);
168
169
        // If the account is unknown
170
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
171
            throw new \RuntimeException(sprintf('Unknown account "%s"', $name), 1475495500);
172
        }
173
174
        // Enable and persist the account
175
        try {
176
            $doctrineAccount->setActive(false);
177
            $this->entityManager->persist($doctrineAccount);
178
            $this->entityManager->flush();
179
        } catch (\Exception $e) {
180
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
181
        }
182
183
        return $this->loadFromDoctrineAccount($doctrineAccount);
184
    }
185
186
    /**
187
     * Delete an account
188
     *
189
     * @param string $name Account name
190
     * @return AccountInterface Account
191
     * @throws \RuntimeException If the account cannot be deleted
192
     */
193
    public function deleteAccount($name)
194
    {
195
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $name]);
196
197
        // If the account is unknown
198
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
199
            throw new \RuntimeException(sprintf('Unknown account "%s"', $name), 1475495500);
200
        }
201
202
        // Enable and persist the account
203
        try {
204
            $this->entityManager->remove($doctrineAccount);
205
            $this->entityManager->flush();
206
        } catch (\Exception $e) {
207
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
208
        }
209
210
        // Create and return a domain account stub
211
        $account = new Account($doctrineAccount->getName());
212
        $account->setActive($doctrineAccount->getActive());
213
        return $account;
214
    }
215
216
    /**
217
     * Rename and return an account
218
     *
219
     * @param string $oldname Old account name
220
     * @param string $newname New account name
221
     * @return AccountInterface Account
222
     * @throws \RuntimeException If the account is unknown
223
     */
224
    public function renameAccount($oldname, $newname)
225
    {
226
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $oldname]);
227
228
        // If the account is unknown
229
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
230
            throw new \RuntimeException(sprintf('Unknown account "%s"', $oldname), 1475495500);
231
        }
232
233
        // Rename and persist the account
234
        try {
235
            $doctrineAccount->setName($newname);
236
            $this->entityManager->persist($doctrineAccount);
237
            $this->entityManager->flush();
238
        } catch (\Exception $e) {
239
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
240
        }
241
242
        // Load and return the renamed account
243
        return $this->loadFromDoctrineAccount($doctrineAccount);
244
    }
245
246
    /**
247
     * Instantiate an account
248
     *
249
     * @param string $name Account name
250
     * @return AccountInterface Account
251
     * @throws \RuntimeException If the account is unknown
252
     */
253
    public function loadAccount($name)
254
    {
255
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $name]);
256
257
        // If the account is unknown
258
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
259
            throw new \RuntimeException(sprintf('Unknown account "%s"', $name), 1475495500);
260
        }
261
262
        return $this->loadFromDoctrineAccount($doctrineAccount);
263
    }
264
265
    /**
266
     * Create domain account from doctrine account
267
     *
268
     * @param DoctrineAccount $doctrineAccount Doctrine account
269
     * @return AccountInterface Domain account
270
     */
271
    protected function loadFromDoctrineAccount(DoctrineAccount $doctrineAccount)
272
    {
273
        $account = new Account($doctrineAccount->getName());
274
275
        // Run through all virtual hosts of this account
276
        /** @var DoctrineVhost $doctrineVhost */
277
        foreach ($doctrineAccount->getVhosts() as $doctrineVhost) {
278
            $doctrinePrimaryDomain = $doctrineVhost->getPrimarydomain();
279
            if ($doctrinePrimaryDomain instanceof DoctrineDomain) {
280
                $primaryDomain = DomainFactory::parseString($doctrinePrimaryDomain->getName());
281
282
                $vhost = new Vhost($primaryDomain, $doctrineVhost->getDocroot(), $doctrineVhost->getType());
283
                $vhost->setPhp($doctrineVhost->getPhp());
284
                $vhost->setRedirectUrl($doctrineVhost->getRedirecturl());
285
                $vhost->setRedirectStatus($doctrineVhost->getRedirectstatus());
286
                if ($doctrineVhost->getHttpport() !== null) {
287
                    $vhost->enableProtocol(Vhost::PROTOCOL_HTTP, $doctrineVhost->getHttpport());
288
                }
289
                if ($doctrineVhost->getHttpsport() !== null) {
290
                    $vhost->enableProtocol(Vhost::PROTOCOL_HTTPS, $doctrineVhost->getHttpsport());
291
                }
292
293
                // Add the wilcard version of the primary domain
294
                if ($doctrinePrimaryDomain->isWildcard()) {
295
                    $vhost->addSecondaryDomain(DomainFactory::parseString('*.'.$primaryDomain));
296
                }
297
298
                // Add all secondary domains
299
                /** @var DoctrineDomain $doctrineDomain */
300
                foreach ($doctrineVhost->getDomains() as $doctrineDomain) {
301
                    if ($doctrineDomain->getName() != $doctrinePrimaryDomain->getName()) {
302
                        $vhost->addSecondaryDomain(DomainFactory::parseString($doctrineDomain->getName()));
303
304
                        if ($doctrineDomain->isWildcard()) {
305
                            $vhost->addSecondaryDomain(DomainFactory::parseString('*.'.$doctrineDomain->getName()));
306
                        }
307
                    }
308
                }
309
310
                $account->addVirtualHost($vhost);
311
            } else {
312
                trigger_error('Skipping virtual host due to missing primary domain', E_USER_NOTICE);
313
            }
314
        }
315
316
        return $account;
317
    }
318
319
320
    /**
321
     * Load a domain (optionally: unassigned)
322
     *
323
     * @param string $name Domain name
324
     * @param AccountInterface $account Optional: Account the domain must belong to while being unassigned at the same time
325
     * @return DomainInterface Domain
326
     * @throws \RuntimeException If the domain is unknown
327
     * @throws \RuntimeException If the domain belongs to another account
328
     */
329
    public function loadDomain($name, AccountInterface $account = null)
330
    {
331
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
332
333
        // If the domain is unknown
334
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
335
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475915909);
336
        }
337
338
        // If only an unassigned domain should be returned
339
        if ($account instanceof Account) {
340
            // If the domain belongs to another account
341
            if ($doctrineDomain->getAccount()->getName() != $account->getName()) {
342
                throw new \RuntimeException(
343
                    sprintf(
344
                        'Domain "%s" belongs to another account ("%s")',
345
                        $name,
346
                        $doctrineDomain->getAccount()->getName()
347
                    ),
348
                    1475917184
349
                );
350
            }
351
352
            // If the domain is already assigned to another virtual host
353
            if ($doctrineDomain->getVhost() instanceof DoctrineVhost) {
354
                throw new \RuntimeException(
355
                    sprintf('Domain "%s" is already assigned to virtual host', $name),
356
                    1475917298
357
                );
358
            }
359
        }
360
361
        return $this->loadFromDoctrineDomain($doctrineDomain);
362
    }
363
364
    /**
365
     * Create a domain
366
     *
367
     * @param string $name Domain name
368
     * @param Account $account Account the domain belongs to
369
     * @return DomainInterface Domain
370
     * @throws \RuntimeException If the account is unknown
371
     */
372
    public function createDomain($name, AccountInterface $account)
373
    {
374
        $doctrineAccount = $this->accountRepository->findOneBy(['name' => $account->getName()]);
375
376
        // If the account is unknown
377
        if (!$doctrineAccount instanceof \Tollwerk\Admin\Infrastructure\Model\Account) {
378
            throw new \RuntimeException(sprintf('Unknown account "%s"', $name), 1475495500);
379
        }
380
381
        // Create the new domain
382
        $doctrineDomain = new DoctrineDomain();
383
        $doctrineDomain->setAccount($doctrineAccount);
384
        $doctrineDomain->setActive(false);
385
        $doctrineDomain->setName($name);
386
        $doctrineDomain->setWildcard(false);
387
        $doctrineDomain->setPrimarydomain(false);
388
389
        // Persist the new domain
390
        try {
391
            $this->entityManager->persist($doctrineDomain);
392
            $this->entityManager->flush();
393
        } catch (UniqueConstraintViolationException $e) {
394
            $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
395
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
396
        } catch (\Exception $e) {
397
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
398
        }
399
400
        // Create and return a domain domain
401
        return $this->loadFromDoctrineDomain($doctrineDomain);
0 ignored issues
show
Documentation introduced by
$doctrineDomain is of type object|null, but the function expects a object<Tollwerk\Admin\In...structure\Model\Domain>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
402
    }
403
404
    /**
405
     * Delete a domain
406
     *
407
     * @param string $name Domain name
408
     * @return DomainInterface Domain
409
     * @throws \RuntimeException If the domain cannot be deleted
410
     */
411
    public function deleteDomain($name)
412
    {
413
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
414
415
        // If the domain is unknown
416
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
417
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475921539);
418
        }
419
420
        // If the domain is assigned to a virtual host
421
        if ($doctrineDomain->getVhost() instanceof \Tollwerk\Admin\Infrastructure\Model\Vhost) {
422
            throw new \RuntimeException(
423
                sprintf('Domain "%s" is assigned to a virtual host, please release the assignment first', $name),
424
                1475921740
425
            );
426
        }
427
428
        // Enable and persist the account
429
        try {
430
            $this->entityManager->remove($doctrineDomain);
431
            $this->entityManager->flush();
432
        } catch (\Exception $e) {
433
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
434
        }
435
436
        // Create and return a domain domain stub
437
        return $this->loadFromDoctrineDomain($doctrineDomain);
438
    }
439
440
    /**
441
     * Enable a domain
442
     *
443
     * @param string $name Domain name
444
     * @return DomainInterface Domain
445
     * @throws \RuntimeException If the domain cannot be enabled
446
     */
447
    public function enableDomain($name)
448
    {
449
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
450
451
        // If the domain is unknown
452
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
453
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475921539);
454
        }
455
456
        // Enable and persist the account
457
        try {
458
            $doctrineDomain->setActive(true);
459
            $this->entityManager->persist($doctrineDomain);
460
            $this->entityManager->flush();
461
        } catch (\Exception $e) {
462
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
463
        }
464
465
        return $this->loadFromDoctrineDomain($doctrineDomain);
466
    }
467
468
    /**
469
     * Disable a domain
470
     *
471
     * @param string $name Domain name
472
     * @return DomainInterface Domain
473
     * @throws \RuntimeException If the domain cannot be disabled
474
     */
475
    public function disableDomain($name)
476
    {
477
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
478
479
        // If the domain is unknown
480
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
481
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475921539);
482
        }
483
484
        // Enable and persist the account
485
        try {
486
            $doctrineDomain->setActive(false);
487
            $this->entityManager->persist($doctrineDomain);
488
            $this->entityManager->flush();
489
        } catch (\Exception $e) {
490
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
491
        }
492
493
        return $this->loadFromDoctrineDomain($doctrineDomain);
494
    }
495
496
    /**
497
     * Enable a domain wildcard
498
     *
499
     * @param string $name Domain name
500
     * @return DomainInterface Domain
501
     * @throws \RuntimeException If the domain cannot be enabled
502
     */
503
    public function enableDomainWildcard($name)
504
    {
505
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
506
507
        // If the domain is unknown
508
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
509
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475921539);
510
        }
511
512
        // Enable and persist the account
513
        try {
514
            $doctrineDomain->setWildcard(true);
515
            $this->entityManager->persist($doctrineDomain);
516
            $this->entityManager->flush();
517
        } catch (\Exception $e) {
518
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
519
        }
520
521
        return $this->loadFromDoctrineDomain($doctrineDomain);
522
    }
523
524
    /**
525
     * Disable a domain wildcard
526
     *
527
     * @param string $name Domain name
528
     * @return DomainInterface Domain
529
     * @throws \RuntimeException If the domain cannot be disabled
530
     */
531
    public function disableDomainWildcard($name)
532
    {
533
        $doctrineDomain = $this->domainRepository->findOneBy(['name' => $name]);
534
535
        // If the domain is unknown
536
        if (!$doctrineDomain instanceof \Tollwerk\Admin\Infrastructure\Model\Domain) {
537
            throw new \RuntimeException(sprintf('Unknown domain "%s"', $name), 1475921539);
538
        }
539
540
        // Enable and persist the account
541
        try {
542
            $doctrineDomain->setWildcard(false);
543
            $this->entityManager->persist($doctrineDomain);
544
            $this->entityManager->flush();
545
        } catch (\Exception $e) {
546
            throw new \RuntimeException($e->getMessage(), $e->getCode() || 1475925451);
547
        }
548
549
        return $this->loadFromDoctrineDomain($doctrineDomain);
550
    }
551
552
    /**
553
     * Create domain domain from doctrine domain
554
     *
555
     * @param DoctrineDomain $doctrineDomain Doctrine domain
556
     * @return DomainInterface Domain domain
557
     */
558
    protected function loadFromDoctrineDomain(DoctrineDomain $doctrineDomain)
559
    {
560
        return DomainFactory::parseString($doctrineDomain->getName());
561
    }
562
}
563