Completed
Push — master ( 9dfd32...d80879 )
by Niels
04:05
created

Domain::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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
67
        // Unpack domain config
68
        $data = is_array($config) ? $config : \GuzzleHttp\Psr7\parse_query($config);
69
        $this->domainName = $data['domain'];
70
71
        // Determine owner
72
        if ($data['username'] === $context->getUsername()) {
73
            $this->owner = $context->getContextUser();
74
        } else {
75
            throw new DirectAdminException('Could not determine relationship between context user and domain');
76
        }
77
78
        // Parse plain options
79
        $bandwidths = array_map('trim', explode('/', $data['bandwidth']));
80
        $this->bandwidthUsed = floatval($bandwidths[0]);
81
        $this->bandwidthLimit = ctype_alpha($bandwidths[1]) ? null : floatval($bandwidths[1]);
82
        $this->diskUsage = floatval($data['quota']);
83
84
        $this->aliases = array_filter(explode('|', $data['alias_pointers']));
85
        $this->pointers = array_filter(explode('|', $data['pointers']));
86
    }
87
88
    /**
89
     * Creates a new domain under the specified user.
90
     *
91
     * @param User $user Owner of the domain
92
     * @param string $domainName Domain name to create
93
     * @param float|null $bandwidthLimit Bandwidth limit in MB, or NULL to share with account
94
     * @param float|null $diskLimit Disk limit in MB, or NULL to share with account
95
     * @param bool|null $ssl Whether SSL is to be enabled, or NULL to fallback to account default
96
     * @param bool|null $php Whether PHP is to be enabled, or NULL to fallback to account default
97
     * @param bool|null $cgi Whether CGI is to be enabled, or NULL to fallback to account default
98
     * @return Domain The newly created domain
99
     */
100
    public static function create(User $user, $domainName, $bandwidthLimit = null, $diskLimit = null, $ssl = null, $php = null, $cgi = null)
101
    {
102
        $options = [
103
            'action' => 'create',
104
            'domain' => $domainName,
105
            (isset($bandwidthLimit) ? 'bandwidth' : 'ubandwidth') => $bandwidthLimit,
106
            (isset($diskLimit) ? 'quota' : 'uquota') => $diskLimit,
107
            'ssl' => Conversion::onOff($ssl, $user->hasSSL()),
108
            'php' => Conversion::onOff($php, $user->hasPHP()),
109
            'cgi' => Conversion::onOff($cgi, $user->hasCGI()),
110
        ];
111
        $user->getContext()->invokePost('DOMAIN', $options);
112
        $config = $user->getContext()->invokeGet('ADDITIONAL_DOMAINS');
113
        return new self($domainName, $user->getContext(), $config[$domainName]);
114
    }
115
116
    /**
117
     * Creates a new email forwarder.
118
     *
119
     * @param string $prefix Part of the email address before the @
120
     * @param string|string[] $recipients One or more recipients
121
     * @return Forwarder The newly created forwarder
122
     */
123
    public function createForwarder($prefix, $recipients)
124
    {
125
        return Forwarder::create($this, $prefix, $recipients);
126
    }
127
128
    /**
129
     * Creates a new mailbox.
130
     *
131
     * @param string $prefix Prefix for the account
132
     * @param string $password Password for the account
133
     * @param int|null $quota Quota in megabytes, or zero/null for unlimited
134
     * @param int|null $sendLimit Send limit, or 0 for unlimited, or null for system default
135
     * @return Mailbox The newly created mailbox
136
     */
137
    public function createMailbox($prefix, $password, $quota = null, $sendLimit = null)
138
    {
139
        return Mailbox::create($this, $prefix, $password, $quota, $sendLimit);
140
    }
141
142
    /**
143
     * Creates a pointer or alias.
144
     *
145
     * @param string $domain
146
     * @param bool $alias
147
     */
148
    public function createPointer($domain, $alias = false)
149
    {
150
        $parameters = [
151
            'domain' => $this->domainName,
152
            'from' => $domain,
153
            'action' => 'add',
154
        ];
155
        if ($alias) {
156
            $parameters['alias'] = 'yes';
157
            $list = &$this->aliases;
158
        } else {
159
            $list = &$this->pointers;
160
        }
161
        $this->getContext()->invokePost('DOMAIN_POINTER', $parameters);
162
        $list[] = $domain;
163
        $list = array_unique($list);
164
    }
165
166
    /**
167
     * Creates a new subdomain.
168
     *
169
     * @param string $prefix Prefix to add before the domain name
170
     * @return Subdomain The newly created subdomain
171
     */
172
    public function createSubdomain($prefix)
173
    {
174
        return Subdomain::create($this, $prefix);
175
    }
176
177
    /**
178
     * Deletes this domain from the user.
179
     */
180
    public function delete()
181
    {
182
        $this->getContext()->invokePost('DOMAIN', [
183
            'delete' => true,
184
            'confirmed' => true,
185
            'select0' => $this->domainName,
186
        ]);
187
        $this->owner->clearCache();
188
    }
189
190
    /**
191
     * @return string[] List of aliases for this domain
192
     */
193
    public function getAliases()
194
    {
195
        return $this->aliases;
196
    }
197
198
    /**
199
     * @return float Bandwidth used in megabytes
200
     */
201
    public function getBandwidthUsed()
202
    {
203
        return $this->bandwidthUsed;
204
    }
205
206
    /**
207
     * @return float|null Bandwidth quotum in megabytes, or NULL for unlimited
208
     */
209
    public function getBandwidthLimit()
210
    {
211
        return $this->bandwidthLimit;
212
    }
213
214
    /**
215
     * @return string|null Currently configured catch-all configuration
216
     */
217
    public function getCatchall()
218
    {
219
        $value = $this->getContext()->invokeGet('EMAIL_CATCH_ALL', ['domain' => $this->domainName]);
220
        return isset($value['value']) ? $value['value'] : null;
221
    }
222
223
    /**
224
     * @return float Disk usage in megabytes
225
     */
226
    public function getDiskUsage()
227
    {
228
        return $this->diskUsage;
229
    }
230
231
    /**
232
     * @return string The real domain name
233
     */
234
    public function getDomainName()
235
    {
236
        return $this->domainName;
237
    }
238
239
    /**
240
     * Returns unified sorted list of main domain name, aliases and pointers.
241
     *
242
     * @return string[]
243
     */
244
    public function getDomainNames()
245
    {
246
        return $this->getCache('domainNames', function () {
247
            $list = array_merge($this->aliases, $this->pointers, [$this->getDomainName()]);
248
            sort($list);
249
            return $list;
250
        });
251
    }
252
253
    /**
254
     * @return Forwarder[] Associative array of forwarders
255
     */
256 View Code Duplication
    public function getForwarders()
257
    {
258
        return $this->getCache(self::CACHE_FORWARDERS, function () {
259
            $forwarders = $this->getContext()->invokeGet('EMAIL_FORWARDERS', [
260
                'domain' => $this->getDomainName(),
261
            ]);
262
            return DomainObject::toDomainObjectArray($forwarders, Forwarder::class, $this);
263
        });
264
    }
265
266
    /**
267
     * @return Mailbox[] Associative array of mailboxes
268
     */
269 View Code Duplication
    public function getMailboxes()
270
    {
271
        return $this->getCache(self::CACHE_MAILBOXES, function () {
272
            $boxes = $this->getContext()->invokeGet('POP', [
273
                'domain' => $this->getDomainName(),
274
                'action' => 'full_list',
275
            ]);
276
            return DomainObject::toDomainObjectArray($boxes, Mailbox::class, $this);
277
        });
278
    }
279
280
    /**
281
     * @return User
282
     */
283
    public function getOwner()
284
    {
285
        return $this->owner;
286
    }
287
288
    /**
289
     * @return string[] List of domain pointers for this domain
290
     */
291
    public function getPointers()
292
    {
293
        return $this->pointers;
294
    }
295
296
    /**
297
     * @return Subdomain[] Associative array of subdomains
298
     */
299
    public function getSubdomains()
300
    {
301
        return $this->getCache(self::CACHE_SUBDOMAINS, function () {
302
            $subs = $this->getContext()->invokeGet('SUBDOMAINS', ['domain' => $this->getDomainName()]);
303
            $subs = array_combine($subs, $subs);
304
            return DomainObject::toDomainObjectArray($subs, Subdomain::class, $this);
305
        });
306
    }
307
308
    /**
309
     * Invokes a POST command on a domain object.
310
     *
311
     * @param string $command Command to invoke
312
     * @param string $action Action to execute
313
     * @param array $parameters Additional options for the command
314
     * @param bool $clearCache Whether to clear the domain cache on success
315
     * @return array Response from the API
316
     */
317
    public function invokePost($command, $action, $parameters = [], $clearCache = true)
318
    {
319
        $response = $this->getContext()->invokePost($command, array_merge([
320
            'action' => $action,
321
            'domain' => $this->domainName,
322
        ], $parameters));
323
        if ($clearCache) {
324
            $this->clearCache();
325
        }
326
        return $response;
327
    }
328
329
    /**
330
     * @param string $newValue New address for the catch-all, or one of the CATCHALL_ constants
331
     */
332
    public function setCatchall($newValue)
333
    {
334
        $parameters = array_merge(['domain' => $this->domainName, 'update' => 'Update'],
335
            (empty($newValue) || $newValue[0] == ':') ? ['catch' => $newValue] : ['catch' => 'address', 'value' => $newValue]);
336
        $this->getContext()->invokePost('EMAIL_CATCH_ALL', $parameters);
337
    }
338
339
    /**
340
     * Allows Domain object to be passed as a string with its domain name.
341
     *
342
     * @return string
343
     */
344
    public function __toString()
345
    {
346
        return $this->getDomainName();
347
    }
348
}
349