User::setDiskLimit()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 1
nop 1
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\Users;
12
13
use Omines\DirectAdmin\Context\ResellerContext;
14
use Omines\DirectAdmin\Context\UserContext;
15
use Omines\DirectAdmin\DirectAdmin;
16
use Omines\DirectAdmin\DirectAdminException;
17
use Omines\DirectAdmin\Objects\Database;
18
use Omines\DirectAdmin\Objects\Domain;
19
use Omines\DirectAdmin\Objects\BaseObject;
20
use Omines\DirectAdmin\Utility\Conversion;
21
22
/**
23
 * User.
24
 *
25
 * @author Niels Keurentjes <[email protected]>
26
 */
27
class User extends BaseObject
28
{
29
    const CACHE_CONFIG = 'config';
30
    const CACHE_DATABASES = 'databases';
31
    const CACHE_USAGE = 'usage';
32
33
    /** @var Domain[] * */
34
    private $domains;
35
36
    /**
37
     * Construct the object.
38
     *
39
     * @param string $name Username of the account
40
     * @param UserContext $context The context managing this object
41
     * @param mixed|null $config An optional preloaded configuration
42
     */
43
    public function __construct($name, UserContext $context, $config = null)
44
    {
45
        parent::__construct($name, $context);
46
        if (isset($config)) {
47
            $this->setCache(self::CACHE_CONFIG, $config);
48
        }
49
    }
50
51
    /**
52
     * Clear the object's internal cache.
53
     */
54
    public function clearCache()
55
    {
56
        unset($this->domains);
57
        parent::clearCache();
58
    }
59
60
    /**
61
     * Creates a new database under this user.
62
     *
63
     * @param string $name Database name, without <user>_ prefix
64
     * @param string $username Username to access the database with, without <user>_ prefix
65
     * @param string|null $password Password, or null if database user already exists
66
     * @return Database Newly created database
67
     */
68
    public function createDatabase($name, $username, $password = null)
69
    {
70
        $db = Database::create($this->getSelfManagedUser(), $name, $username, $password);
71
        $this->clearCache();
72
        return $db;
73
    }
74
75
    /**
76
     * Creates a new domain under this user.
77
     *
78
     * @param string $domainName Domain name to create
79
     * @param float|null $bandwidthLimit Bandwidth limit in MB, or NULL to share with account
80
     * @param float|null $diskLimit Disk limit in MB, or NULL to share with account
81
     * @param bool|null $ssl Whether SSL is to be enabled, or NULL to fallback to account default
82
     * @param bool|null $php Whether PHP is to be enabled, or NULL to fallback to account default
83
     * @param bool|null $cgi Whether CGI is to be enabled, or NULL to fallback to account default
84
     * @return Domain Newly created domain
85
     */
86
    public function createDomain($domainName, $bandwidthLimit = null, $diskLimit = null, $ssl = null, $php = null, $cgi = null)
87
    {
88
        $domain = Domain::create($this->getSelfManagedUser(), $domainName, $bandwidthLimit, $diskLimit, $ssl, $php, $cgi);
89
        $this->clearCache();
90
        return $domain;
91
    }
92
93
    /**
94
     * @return string The username
95
     */
96
    public function getUsername()
97
    {
98
        return $this->getName();
99
    }
100
101
    /**
102
     * Returns the bandwidth limit of the user.
103
     *
104
     * @return float|null Limit in megabytes, or null for unlimited
105
     */
106
    public function getBandwidthLimit()
107
    {
108
        return floatval($this->getConfig('bandwidth')) ?: null;
109
    }
110
111
    /**
112
     * Returns the current period's bandwidth usage in megabytes.
113
     *
114
     * @return float
115
     */
116
    public function getBandwidthUsage()
117
    {
118
        return floatval($this->getUsage('bandwidth'));
119
    }
120
121
    /**
122
     * Returns the database quota of the user.
123
     *
124
     * @return int|null Limit, or null for unlimited
125
     */
126
    public function getDatabaseLimit()
127
    {
128
        return intval($this->getConfig('mysql')) ?: null;
129
    }
130
131
    /**
132
     * Returns the current number databases in use.
133
     *
134
     * @return int
135
     */
136
    public function getDatabaseUsage()
137
    {
138
        return intval($this->getUsage('mysql'));
139
    }
140
141
    /**
142
     * Returns the disk quota of the user.
143
     *
144
     * @return float|null Limit in megabytes, or null for unlimited
145
     */
146
    public function getDiskLimit()
147
    {
148
        return floatval($this->getConfig('quota')) ?: null;
149
    }
150
151
    /**
152
     * Returns the current disk usage in megabytes.
153
     *
154
     * @return float
155
     */
156
    public function getDiskUsage()
157
    {
158
        return floatval($this->getUsage('quota'));
159
    }
160
161
    /**
162
     * @return Domain|null The default domain for the user, if any
163
     */
164
    public function getDefaultDomain()
165
    {
166
        if (empty($name = $this->getConfig('domain'))) {
167
            return null;
168
        }
169
        return $this->getDomain($name);
170
    }
171
172
    /**
173
     * Returns maximum number of domains allowed to this user, or NULL for unlimited.
174
     *
175
     * @return int|null
176
     */
177
    public function getDomainLimit()
178
    {
179
        return intval($this->getConfig('vdomains')) ?: null;
180
    }
181
182
    /**
183
     * Returns number of domains owned by this user.
184
     *
185
     * @return int
186
     */
187
    public function getDomainUsage()
188
    {
189
        return intval($this->getUsage('vdomains'));
190
    }
191
192
    /**
193
     * Returns whether the user is currently suspended.
194
     *
195
     * @return bool
196
     */
197
    public function isSuspended()
198
    {
199
        return Conversion::toBool($this->getConfig('suspended'));
200
    }
201
202
    /**
203
     * @return Domain[]
204
     */
205
    public function getDatabases()
206
    {
207
        return $this->getCache(self::CACHE_DATABASES, function () {
208
            $databases = [];
209
            foreach ($this->getSelfManagedContext()->invokeApiGet('DATABASES') as $fullName) {
210
                list($user, $db) = explode('_', $fullName, 2);
211
                if ($this->getUsername() != $user) {
212
                    throw new DirectAdminException('Username incorrect on database ' . $fullName);
213
                }
214
                $databases[$db] = new Database($db, $this, $this->getSelfManagedContext());
215
            }
216
            return $databases;
217
        });
218
    }
219
220
    /**
221
     * @param string $domainName
222
     * @return null|Domain
223
     */
224
    public function getDomain($domainName)
225
    {
226
        if (!isset($this->domains)) {
227
            $this->getDomains();
228
        }
229
        return isset($this->domains[$domainName]) ? $this->domains[$domainName] : null;
230
    }
231
232
    /**
233
     * @return Domain[]
234
     */
235
    public function getDomains()
236
    {
237
        if (!isset($this->domains)) {
238
            if (!$this->isSelfManaged()) {
239
                $this->domains = $this->impersonate()->getDomains();
240
            } else {
241
                $this->domains = BaseObject::toRichObjectArray($this->getContext()->invokeApiGet('ADDITIONAL_DOMAINS'), Domain::class, $this->getContext());
242
            }
243
        }
244
        return $this->domains;
245
    }
246
247
    /**
248
     * @return string The user type, as one of the ACCOUNT_TYPE_ constants in the DirectAdmin class
249
     */
250
    public function getType()
251
    {
252
        return $this->getConfig('usertype');
253
    }
254
255
    /**
256
     * @return bool Whether the user can use CGI
257
     */
258
    public function hasCGI()
259
    {
260
        return Conversion::toBool($this->getConfig('cgi'));
261
    }
262
263
    /**
264
     * @return bool Whether the user can use PHP
265
     */
266
    public function hasPHP()
267
    {
268
        return Conversion::toBool($this->getConfig('php'));
269
    }
270
271
    /**
272
     * @return bool Whether the user can use SSL
273
     */
274
    public function hasSSL()
275
    {
276
        return Conversion::toBool($this->getConfig('ssl'));
277
    }
278
279
    /**
280
     * @return UserContext
281
     */
282
    public function impersonate()
283
    {
284
        /** @var ResellerContext $context */
285
        if (!($context = $this->getContext()) instanceof ResellerContext) {
286
            throw new DirectAdminException('You need to be at least a reseller to impersonate');
287
        }
288
        return $context->impersonateUser($this->getUsername());
289
    }
290
291
    /**
292
     * Modifies the configuration of the user. For available keys in the array check the documentation on
293
     * CMD_API_MODIFY_USER in the linked document.
294
     *
295
     * @param array $newConfig Associative array of values to be modified
296
     * @url http://www.directadmin.com/api.html#modify
297
     */
298
    public function modifyConfig(array $newConfig)
299
    {
300
        $this->getContext()->invokeApiPost('MODIFY_USER', array_merge(
301
                $this->loadConfig(),
302
                Conversion::processUnlimitedOptions($newConfig),
303
                ['action' => 'customize', 'user' => $this->getUsername()]
304
        ));
305
        $this->clearCache();
306
    }
307
308
    /**
309
     * @param bool $newValue Whether catch-all email is enabled for this user
310
     */
311
    public function setAllowCatchall($newValue)
312
    {
313
        $this->modifyConfig(['catchall' => Conversion::onOff($newValue)]);
314
    }
315
316
    /**
317
     * @param float|null $newValue New value, or NULL for unlimited
318
     */
319
    public function setBandwidthLimit($newValue)
320
    {
321
        $this->modifyConfig(['bandwidth' => isset($newValue) ? floatval($newValue) : null]);
322
    }
323
324
    /**
325
     * @param float|null $newValue New value, or NULL for unlimited
326
     */
327
    public function setDiskLimit($newValue)
328
    {
329
        $this->modifyConfig(['quota' => isset($newValue) ? floatval($newValue) : null]);
330
    }
331
332
    /**
333
     * @param int|null $newValue New value, or NULL for unlimited
334
     */
335
    public function setDomainLimit($newValue)
336
    {
337
        $this->modifyConfig(['vdomains' => isset($newValue) ? intval($newValue) : null]);
338
    }
339
340
    /**
341
     * Constructs the correct object from the given user config.
342
     *
343
     * @param array $config The raw config from DirectAdmin
344
     * @param UserContext $context The context within which the config was retrieved
345
     * @return Admin|Reseller|User The correct object
346
     * @throws DirectAdminException If the user type could not be determined
347
     */
348
    public static function fromConfig($config, UserContext $context)
349
    {
350
        $name = $config['username'];
351
        switch ($config['usertype']) {
352
            case DirectAdmin::ACCOUNT_TYPE_USER:
353
                return new self($name, $context, $config);
354
            case DirectAdmin::ACCOUNT_TYPE_RESELLER:
355
                return new Reseller($name, $context, $config);
356
            case DirectAdmin::ACCOUNT_TYPE_ADMIN:
357
                return new Admin($name, $context, $config);
358
            default:
359
                throw new DirectAdminException("Unknown user type '$config[usertype]'");
360
        }
361
    }
362
363
    /**
364
     * Internal function to safe guard config changes and cache them.
365
     *
366
     * @param string $item Config item to retrieve
367
     * @return mixed The value of the config item, or NULL
368
     */
369
    private function getConfig($item)
370
    {
371
        return $this->getCacheItem(self::CACHE_CONFIG, $item, function () {
372
            return $this->loadConfig();
373
        });
374
    }
375
376
    /**
377
     * Internal function to safe guard usage changes and cache them.
378
     *
379
     * @param string $item Usage item to retrieve
380
     * @return mixed The value of the stats item, or NULL
381
     */
382
    private function getUsage($item)
383
    {
384
        return $this->getCacheItem(self::CACHE_USAGE, $item, function () {
385
            return $this->getContext()->invokeApiGet('SHOW_USER_USAGE', ['user' => $this->getUsername()]);
386
        });
387
    }
388
389
    /**
390
     * @return UserContext The local user context
391
     */
392
    protected function getSelfManagedContext()
393
    {
394
        return $this->isSelfManaged() ? $this->getContext() : $this->impersonate();
395
    }
396
397
    /**
398
     * @return User The user acting as himself
399
     */
400
    protected function getSelfManagedUser()
401
    {
402
        return $this->isSelfManaged() ? $this : $this->impersonate()->getContextUser();
403
    }
404
405
    /**
406
     * @return bool Whether the account is managing itself
407
     */
408
    protected function isSelfManaged()
409
    {
410
        return $this->getUsername() === $this->getContext()->getUsername();
411
    }
412
413
    /**
414
     * Loads the current user configuration from the server.
415
     *
416
     * @return array
417
     */
418
    private function loadConfig()
419
    {
420
        return $this->getContext()->invokeApiGet('SHOW_USER_CONFIG', ['user' => $this->getUsername()]);
421
    }
422
}
423