Completed
Push — master ( 79ff26...9e9048 )
by Niels
02:04
created

Domain::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 5
rs 9.4285
c 1
b 0
f 0
cc 2
eloc 3
nc 1
nop 3
1
<?php
2
3
/*
4
 * DirectAdmin API Client
5
 * (c) Omines Internetbureau B.V. - https://omines.nl/
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Omines\DirectAdmin\Objects;
12
13
use Omines\DirectAdmin\Context\UserContext;
14
use Omines\DirectAdmin\DirectAdminException;
15
use Omines\DirectAdmin\Objects\Domains\Subdomain;
16
use Omines\DirectAdmin\Objects\Email\Forwarder;
17
use Omines\DirectAdmin\Objects\Email\Mailbox;
18
use Omines\DirectAdmin\Objects\Users\User;
19
use Omines\DirectAdmin\Utility\Conversion;
20
21
/**
22
 * Encapsulates a domain and its derived objects, like aliases, pointers and mailboxes.
23
 *
24
 * @author Niels Keurentjes <[email protected]>
25
 */
26
class Domain extends BaseObject
27
{
28
    const CACHE_FORWARDERS = 'forwarders';
29
    const CACHE_MAILBOXES = 'mailboxes';
30
    const CACHE_SUBDOMAINS = 'subdomains';
31
32
    const CATCHALL_BLACKHOLE = ':blackhole:';
33
    const CATCHALL_FAIL = ':fail:';
34
35
    /** @var string */
36
    private $domainName;
37
38
    /** @var User */
39
    private $owner;
40
41
    /** @var string[] */
42
    private $aliases;
43
44
    /** @var string[] */
45
    private $pointers;
46
47
    /** @var float */
48
    private $bandwidthUsed;
49
50
    /** @var float|null */
51
    private $bandwidthLimit;
52
53
    /** @var float */
54
    private $diskUsage;
55
56
    /**
57
     * Construct the object.
58
     *
59
     * @param string $name The domain name
60
     * @param UserContext $context The owning user context
61
     * @param string|array $config The basic config string as returned by CMD_API_ADDITIONAL_DOMAINS
62
     */
63
    public function __construct($name, UserContext $context, $config)
64
    {
65
        parent::__construct($name, $context);
66
        $this->setConfig($context, is_array($config) ? $config : \GuzzleHttp\Psr7\parse_query($config));
67
    }
68
69
    /**
70
     * Creates a new domain under the specified user.
71
     *
72
     * @param User $user Owner of the domain
73
     * @param string $domainName Domain name to create
74
     * @param float|null $bandwidthLimit Bandwidth limit in MB, or NULL to share with account
75
     * @param float|null $diskLimit Disk limit in MB, or NULL to share with account
76
     * @param bool|null $ssl Whether SSL is to be enabled, or NULL to fallback to account default
77
     * @param bool|null $php Whether PHP is to be enabled, or NULL to fallback to account default
78
     * @param bool|null $cgi Whether CGI is to be enabled, or NULL to fallback to account default
79
     * @return Domain The newly created domain
80
     */
81
    public static function create(User $user, $domainName, $bandwidthLimit = null, $diskLimit = null, $ssl = null, $php = null, $cgi = null)
82
    {
83
        $options = [
84
            'action' => 'create',
85
            'domain' => $domainName,
86
            (isset($bandwidthLimit) ? 'bandwidth' : 'ubandwidth') => $bandwidthLimit,
87
            (isset($diskLimit) ? 'quota' : 'uquota') => $diskLimit,
88
            'ssl' => Conversion::onOff($ssl, $user->hasSSL()),
89
            'php' => Conversion::onOff($php, $user->hasPHP()),
90
            'cgi' => Conversion::onOff($cgi, $user->hasCGI()),
91
        ];
92
        $user->getContext()->invokeApiPost('DOMAIN', $options);
93
        $config = $user->getContext()->invokeApiGet('ADDITIONAL_DOMAINS');
94
        return new self($domainName, $user->getContext(), $config[$domainName]);
95
    }
96
97
    /**
98
     * Creates a new email forwarder.
99
     *
100
     * @param string $prefix Part of the email address before the @
101
     * @param string|string[] $recipients One or more recipients
102
     * @return Forwarder The newly created forwarder
103
     */
104
    public function createForwarder($prefix, $recipients)
105
    {
106
        return Forwarder::create($this, $prefix, $recipients);
107
    }
108
109
    /**
110
     * Creates a new mailbox.
111
     *
112
     * @param string $prefix Prefix for the account
113
     * @param string $password Password for the account
114
     * @param int|null $quota Quota in megabytes, or zero/null for unlimited
115
     * @param int|null $sendLimit Send limit, or 0 for unlimited, or null for system default
116
     * @return Mailbox The newly created mailbox
117
     */
118
    public function createMailbox($prefix, $password, $quota = null, $sendLimit = null)
119
    {
120
        return Mailbox::create($this, $prefix, $password, $quota, $sendLimit);
121
    }
122
123
    /**
124
     * Creates a pointer or alias.
125
     *
126
     * @param string $domain
127
     * @param bool $alias
128
     */
129
    public function createPointer($domain, $alias = false)
130
    {
131
        $parameters = [
132
            'domain' => $this->domainName,
133
            'from' => $domain,
134
            'action' => 'add',
135
        ];
136
        if ($alias) {
137
            $parameters['alias'] = 'yes';
138
            $list = &$this->aliases;
139
        } else {
140
            $list = &$this->pointers;
141
        }
142
        $this->getContext()->invokeApiPost('DOMAIN_POINTER', $parameters);
143
        $list[] = $domain;
144
        $list = array_unique($list);
145
    }
146
147
    /**
148
     * Creates a new subdomain.
149
     *
150
     * @param string $prefix Prefix to add before the domain name
151
     * @return Subdomain The newly created subdomain
152
     */
153
    public function createSubdomain($prefix)
154
    {
155
        return Subdomain::create($this, $prefix);
156
    }
157
158
    /**
159
     * Deletes this domain from the user.
160
     */
161
    public function delete()
162
    {
163
        $this->getContext()->invokeApiPost('DOMAIN', [
164
            'delete' => true,
165
            'confirmed' => true,
166
            'select0' => $this->domainName,
167
        ]);
168
        $this->owner->clearCache();
169
    }
170
171
    /**
172
     * @return string[] List of aliases for this domain
173
     */
174
    public function getAliases()
175
    {
176
        return $this->aliases;
177
    }
178
179
    /**
180
     * @return float Bandwidth used in megabytes
181
     */
182
    public function getBandwidthUsed()
183
    {
184
        return $this->bandwidthUsed;
185
    }
186
187
    /**
188
     * @return float|null Bandwidth quotum in megabytes, or NULL for unlimited
189
     */
190
    public function getBandwidthLimit()
191
    {
192
        return $this->bandwidthLimit;
193
    }
194
195
    /**
196
     * @return string|null Currently configured catch-all configuration
197
     */
198
    public function getCatchall()
199
    {
200
        $value = $this->getContext()->invokeApiGet('EMAIL_CATCH_ALL', ['domain' => $this->domainName]);
201
        return isset($value['value']) ? $value['value'] : null;
202
    }
203
204
    /**
205
     * @return float Disk usage in megabytes
206
     */
207
    public function getDiskUsage()
208
    {
209
        return $this->diskUsage;
210
    }
211
212
    /**
213
     * @return string The real domain name
214
     */
215
    public function getDomainName()
216
    {
217
        return $this->domainName;
218
    }
219
220
    /**
221
     * Returns unified sorted list of main domain name, aliases and pointers.
222
     *
223
     * @return string[]
224
     */
225
    public function getDomainNames()
226
    {
227
        return $this->getCache('domainNames', function () {
228
            $list = array_merge($this->aliases, $this->pointers, [$this->getDomainName()]);
229
            sort($list);
230
            return $list;
231
        });
232
    }
233
234
    /**
235
     * @return Forwarder[] Associative array of forwarders
236
     */
237 View Code Duplication
    public function getForwarders()
238
    {
239
        return $this->getCache(self::CACHE_FORWARDERS, function () {
240
            $forwarders = $this->getContext()->invokeApiGet('EMAIL_FORWARDERS', [
241
                'domain' => $this->getDomainName(),
242
            ]);
243
            return DomainObject::toDomainObjectArray($forwarders, Forwarder::class, $this);
244
        });
245
    }
246
247
    /**
248
     * @return Mailbox[] Associative array of mailboxes
249
     */
250 View Code Duplication
    public function getMailboxes()
251
    {
252
        return $this->getCache(self::CACHE_MAILBOXES, function () {
253
            $boxes = $this->getContext()->invokeApiGet('POP', [
254
                'domain' => $this->getDomainName(),
255
                'action' => 'full_list',
256
            ]);
257
            return DomainObject::toDomainObjectArray($boxes, Mailbox::class, $this);
258
        });
259
    }
260
261
    /**
262
     * @return User
263
     */
264
    public function getOwner()
265
    {
266
        return $this->owner;
267
    }
268
269
    /**
270
     * @return string[] List of domain pointers for this domain
271
     */
272
    public function getPointers()
273
    {
274
        return $this->pointers;
275
    }
276
277
    /**
278
     * @return Subdomain[] Associative array of subdomains
279
     */
280
    public function getSubdomains()
281
    {
282
        return $this->getCache(self::CACHE_SUBDOMAINS, function () {
283
            $subs = $this->getContext()->invokeApiGet('SUBDOMAINS', ['domain' => $this->getDomainName()]);
284
            $subs = array_combine($subs, $subs);
285
            return DomainObject::toDomainObjectArray($subs, Subdomain::class, $this);
286
        });
287
    }
288
289
    /**
290
     * Invokes a POST command on a domain object.
291
     *
292
     * @param string $command Command to invoke
293
     * @param string $action Action to execute
294
     * @param array $parameters Additional options for the command
295
     * @param bool $clearCache Whether to clear the domain cache on success
296
     * @return array Response from the API
297
     */
298
    public function invokePost($command, $action, $parameters = [], $clearCache = true)
299
    {
300
        $response = $this->getContext()->invokeApiPost($command, array_merge([
301
            'action' => $action,
302
            'domain' => $this->domainName,
303
        ], $parameters));
304
        if ($clearCache) {
305
            $this->clearCache();
306
        }
307
        return $response;
308
    }
309
310
    /**
311
     * @param string $newValue New address for the catch-all, or one of the CATCHALL_ constants
312
     */
313
    public function setCatchall($newValue)
314
    {
315
        $parameters = array_merge(['domain' => $this->domainName, 'update' => 'Update'],
316
            (empty($newValue) || $newValue[0] == ':') ? ['catch' => $newValue] : ['catch' => 'address', 'value' => $newValue]);
317
        $this->getContext()->invokeApiPost('EMAIL_CATCH_ALL', $parameters);
318
    }
319
320
    /**
321
     * Allows Domain object to be passed as a string with its domain name.
322
     *
323
     * @return string
324
     */
325
    public function __toString()
326
    {
327
        return $this->getDomainName();
328
    }
329
330
    /**
331
     * Sets configuration options from raw DirectAdmin data.
332
     *
333
     * @param UserContext $context Owning user context
334
     * @param array $config An array of settings
335
     */
336
    private function setConfig(UserContext $context, array $config)
337
    {
338
        $this->domainName = $config['domain'];
339
340
        // Determine owner
341
        if ($config['username'] === $context->getUsername()) {
342
            $this->owner = $context->getContextUser();
343
        } else {
344
            throw new DirectAdminException('Could not determine relationship between context user and domain');
345
        }
346
347
        // Parse plain options
348
        $bandwidths = array_map('trim', explode('/', $config['bandwidth']));
349
        $this->bandwidthUsed = floatval($bandwidths[0]);
350
        $this->bandwidthLimit = ctype_alpha($bandwidths[1]) ? null : floatval($bandwidths[1]);
351
        $this->diskUsage = floatval($config['quota']);
352
353
        $this->aliases = array_filter(explode('|', $config['alias_pointers']));
354
        $this->pointers = array_filter(explode('|', $config['pointers']));
355
    }
356
}
357