Accounts::modifyAccount()   F
last analyzed

Complexity

Conditions 40
Paths > 20000

Size

Total Lines 112

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 1640

Importance

Changes 0
Metric Value
dl 0
loc 112
ccs 0
cts 56
cp 0
rs 0
c 0
b 0
f 0
cc 40
nc 2176782337
nop 1
crap 1640

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PreviewTechs\cPanelWHM\WHM;
4
5
use DateTime;
6
use Http\Client\Exception;
7
use PreviewTechs\cPanelWHM\Entity\Account;
8
use PreviewTechs\cPanelWHM\Entity\Domain;
9
use PreviewTechs\cPanelWHM\Entity\DomainUser;
10
use PreviewTechs\cPanelWHM\Entity\SuspendedAccount;
11
use PreviewTechs\cPanelWHM\Exceptions\ClientExceptions;
12
use PreviewTechs\cPanelWHM\WHMClient;
13
14
/**
15
 * Class Accounts
16
 *
17
 * @package PreviewTechs\cPanelWHM\WHM
18
 */
19
class Accounts
20
{
21
    /**
22
     *
23
     * @var WHMClient
24
     */
25
    protected $client;
26
27
    /**
28
     * Accounts constructor.
29
     *
30
     * @param WHMClient $client
31
     */
32
    public function __construct(WHMClient $client)
33
    {
34
        $this->client = $client;
35
    }
36
37
    /**
38
     * Search accounts from your WHM server.
39
     *
40
     * WHM API function: Accounts -> listaccts
41
     *
42
     * $accounts = new Accounts($c);
43
     * $keyword = "search_keyword";
44
     * $searchType = "username";   //valid search types are "domain", "owner", "user", "ip", "package"
45
     * $options = [
46
     *       'searchmethod' => "exact",   //"exact" or "regex",
47
     *       "page" => 1,
48
     *       "limit" => 10,   //per page,
49
     *       "want" => "username"    //A comma-separated list of fields you want to fetch
50
     *   ];
51
     *
52
     * try {
53
     *       $accounts->searchAccounts($keyword, $searchType, $options);
54
     *   } catch (\Http\Client\Exception $e) {
55
     *       echo $e->getMessage();
56
     *   } catch (\PreviewTechs\cPanelWHM\Exceptions\ClientExceptions $e) {
57
     *       echo $e->getMessage();
58
     *   }
59
     *
60
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listaccts
61
     *
62
     * @param null $keyword
63
     * @param null $searchType
64
     * @param array $options
65
     *
66
     * @return array
67
     * @throws ClientExceptions
68
     * @throws Exception
69
     */
70
    public function searchAccounts($keyword = null, $searchType = null, array $options = [])
71
    {
72
        $limit = 10;
73
        $page  = 1;
74
75
        $params = [
76
            'api.version'      => 1,
77
            'api.chunk.enable' => 1,
78
            'api.chunk.size'   => $limit,
79
            'api.chunk.start'  => $page * $limit
80
        ];
81
82
        if ( ! empty($options['limit'])) {
83
            $params['api.chunk.size'] = intval($options['limit']);
84
        }
85
86
        if ( ! empty($options['page'])) {
87
            $params['api.chunk.start'] = intval($options['page']) * $params['api.chunk.size'];
88
        }
89
90 View Code Duplication
        if ( ! empty($searchType) && ! in_array($searchType, ["domain", "owner", "user", "ip", "package"])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
            throw new \InvalidArgumentException("`searchType` must be one of these - domain, owner, user, ip, package");
92
        }
93
94
        if ( ! empty($options['searchmethod']) && ! in_array($options['searchmethod'], ["exact", "regex"])) {
95
            throw new \InvalidArgumentException("options[searchmethod] must be either `regex` or `exact`");
96
        }
97
98
        if ( ! empty($options['want'])) {
99
            $params['want'] = $options['want'];
100
        }
101
102
        if ( ! empty($searchType)) {
103
            $params['searchtype'] = $searchType;
104
        }
105
106
        if ( ! empty($keyword)) {
107
            $params['search'] = $keyword;
108
            empty($searchType) ? $params['searchtype'] = "user" : null;
109
        }
110
111
        $results = $this->client->sendRequest("/json-api/listaccts", "GET", $params);
112
        if (empty($results['data']['acct'])) {
113
            return [];
114
        }
115
116
        $accounts = [];
117
        foreach ($results['data']['acct'] as $account) {
118
            $accounts[] = Account::buildFromArray($account);
119
        }
120
121
        return [
122
            'accounts' => $accounts,
123
            'count'    => $params['api.chunk.size'],
124
            'page'     => $page
125
        ];
126
    }
127
128
    /**
129
     * Get an account details
130
     *
131
     * WHM API function: Accounts -> accountsummary
132
     *
133
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+accountsummary
134
     *
135
     * @param null $user
136
     * @param null $domain
137
     *
138
     * @return null|Account
139
     * @throws ClientExceptions
140
     * @throws Exception
141
     */
142
    public function getDetails($user = null, $domain = null)
143
    {
144
        if (empty($user) && empty($domain)) {
145
            throw ClientExceptions::invalidArgument("You must provide either a username or a domain or both");
146
        }
147
148
        if ( ! empty($user) && ! empty($domain)) {
149
            throw ClientExceptions::invalidArgument(
150
                "You must provide only one argument either user OR domain (not both)"
151
            );
152
        }
153
154
        $params = [];
155
156
        if ( ! empty($user)) {
157
            $params['user'] = $user;
158
        }
159
160
        if ( ! empty($domain)) {
161
            $params['domain'] = $domain;
162
        }
163
164
        $result = $this->client->sendRequest("/json-api/accountsummary", "GET", $params);
165
166
        if (empty($result)) {
167
            return null;
168
        }
169
170
        if ($result['metadata']['reason'] != "OK") {
171
            throw ClientExceptions::recordNotFound(
172
                ! empty($result['metadata']['reason']) ? $result['metadata']['reason'] : "Record not found"
173
            );
174
        }
175
176
        if ( ! empty($result['data']) && is_array($result['data']) && !empty($result['data']['acct'])) {
177
            return Account::buildFromArray($result['data']['acct'][0]);
178
        }
179
180
        return null;
181
    }
182
183
    /**
184
     * This function lists available WHM API 1 functions.
185
     *
186
     * This function only lists the functions that are available to the current user.
187
     * For example, if the authenticated user is a reseller without root -level privileges,
188
     * the function will not list WHM API 1 functions that require root privileges.
189
     *
190
     * WHM API function: Accounts -> applist
191
     *
192
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+applist
193
     *
194
     * @return array
195
     * @throws ClientExceptions
196
     * @throws Exception
197
     */
198
    public function availableFunctions()
199
    {
200
        $result = $this->client->sendRequest("/json-api/applist", 'GET', []);
201
202
        if ( ! empty($result['app']) && sizeof($result['app']) > 0) {
203
            return $result['app'];
204
        }
205
206
        return [];
207
    }
208
209
    /**
210
     * Create a new account. This function creates a cPanel account.
211
     * The function also sets up the new account's domain information.
212
     *
213
     * WHM API function: Accounts -> createacct
214
     *
215
     * @link    https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+createacct
216
     *
217
     * @param Account $account
218
     * @param array $options
219
     *
220
     * @return array
221
     * @throws ClientExceptions
222
     * @throws Exception
223
     */
224
    public function create(Account $account, array $options = [])
225
    {
226
        if (empty($account->getUser())) {
227
            throw ClientExceptions::invalidArgument("You must provide an username to create new account");
228
        }
229
230
        if (empty($account->getDomain())) {
231
            throw ClientExceptions::invalidArgument("You must provide a domain to create new account");
232
        }
233
234
        $params             = [];
235
        $params['username'] = $account->getUser();
236
        $params['domain']   = $account->getDomain();
237
        ! empty($account->getPlanName()) ? $params['plan'] = $account->getPlanName() : null;
238
        ! empty($options['pkgname']) ? $params['pkgname'] = $options['pkgname'] : null;
239
        if ( ! empty($options['savepkg'])) {
240
            if ( ! in_array(intval($options['savepkg']), [0, 1])) {
241
                throw new ClientExceptions("`savepkg` must be either 0 or 1");
242
            }
243
244
            $params['savepkg'] = $options['savepkg'];
245
        }
246
247
        ! empty($options['featurelist']) ? $params['featurelist'] = $options['featurelist'] : null;
248
        if ( ! empty($account->getDiskLimit())) {
249
            if ($account->getDiskLimit() === -1) {
250
                $params['quota'] = 0;
251
            } else {
252
                $params['quota'] = intval($account->getDiskLimit());
253
            }
254
        }
255
256
        ! empty($account->getPassword()) ? $params['password'] = $account->getPassword() : null;
257
        ! empty($account->getIpAddress()) ? $params['ip'] = $account->getIpAddress() : null;
258
        ! empty($account->isCgiEnable()) ? $params['cgi'] = (int)$account->isCgiEnable() : null;
259
        ! empty($account->isSpamAssassinEnable()) ?
260
            $params['spamassassin'] = (int)$account->isSpamAssassinEnable()
261
            : null;
262
        ! empty($account->isFrontPageEnable()) ? $params['frontpage'] = (int)$account->isFrontPageEnable() : null;
263
        ! empty($account->getShell()) ? $params['hasshell'] = 1 : null;
264
        ! empty($account->getEmail()) ? $params['contactemail'] = $account->getEmail() : null;
265
        ! empty($account->getTheme()) ? $params['cpmod'] = 1 : null;
266
267 View Code Duplication
        if ($account->getMaxFTP() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
268
            $params['maxftp'] = "unlimited";
269
        } elseif ($account->getMaxFTP() > 0) {
270
            $params['maxftp'] = intval($account->getMaxFTP());
271
        }
272
273 View Code Duplication
        if ($account->getMaxSQL() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
274
            $params['maxsql'] = "unlimited";
275
        } elseif ($account->getMaxSQL() > 0) {
276
            $params['maxsql'] = intval($account->getMaxSQL());
277
        }
278
279 View Code Duplication
        if ($account->getMaxPOP() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
            $params['maxpop'] = "unlimited";
281
        } elseif ($account->getMaxPOP() > 0) {
282
            $params['maxpop'] = intval($account->getMaxPOP());
283
        }
284
285 View Code Duplication
        if ($account->getMaxMailingList() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286
            $params['maxlst'] = "unlimited";
287
        } elseif ($account->getMaxMailingList() > 0) {
288
            $params['maxlst'] = intval($account->getMaxMailingList());
289
        }
290
291 View Code Duplication
        if ($account->getMaxSubDomain() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
292
            $params['maxsub'] = "unlimited";
293
        } elseif ($account->getMaxSubDomain() > 0) {
294
            $params['maxsub'] = intval($account->getMaxSubDomain());
295
        }
296
297 View Code Duplication
        if ($account->getMaxParkedDomains() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
298
            $params['maxpark'] = "unlimited";
299
        } elseif ($account->getMaxParkedDomains() > 0) {
300
            $params['maxpark'] = intval($account->getMaxParkedDomains());
301
        }
302
303 View Code Duplication
        if ($account->getMaxAddonDomains() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
304
            $params['maxaddon'] = "unlimited";
305
        } elseif ($account->getMaxAddonDomains() > 0) {
306
            $params['maxaddon'] = intval($account->getMaxAddonDomains());
307
        }
308
309 View Code Duplication
        if ($account->getBandwidthLimit() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
310
            $params['bwlimit'] = "unlimited";
311
        } elseif ($account->getBandwidthLimit() > 0) {
312
            $params['bwlimit'] = intval($account->getBandwidthLimit());
313
        }
314
315
        ! empty($options['customip']) ? $params['customip'] = $options['customip'] : null;
316
317
        ! empty($account->getLanguagePreference()) ? $params['language'] = $account->getLanguagePreference() : null;
318
319
        ! empty($options['useregns']) ? $params['useregns'] = $options['useregns'] : null;
320
        ! empty($options['reseller']) ? $params['reseller'] = (int)$options['reseller'] : null;
321
        ! empty($options['forcedns']) ? $params['forcedns'] = (int)$options['forcedns'] : null;
322
323
        ! empty($account->getMailboxFormat()) ? $params['mailbox_format'] = $account->getMailboxFormat() : null;
324
325
        if ( ! empty($options['mxcheck'])) {
326
            if ( ! in_array($options['mxcheck'], ['local', 'secondary', 'remote', 'auto'])) {
327
                throw new ClientExceptions("options[mxcheck] parameters must be one of local, secondary, remote, auto");
328
            }
329
330
            $params['mxcheck'] = $options['mxcheck'];
331
        }
332
333 View Code Duplication
        if ($account->getMaxEmailPerHour() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
334
            $params['max_email_per_hour'] = "unlimited";
335
        } elseif ($account->getMaxEmailPerHour() > 0) {
336
            $params['max_email_per_hour'] = intval($account->getMaxEmailPerHour());
337
        }
338
339
        if ($account->getMaxEmailAccountQuota() === -1) {
340
            $params['max_emailacct_quota'] = "unlimited";
341
        } elseif ($account->getMaxEmailAccountQuota() > 0) {
342
            $params['max_email_per_hour'] = intval($account->getMaxEmailAccountQuota());
343
        }
344
345 View Code Duplication
        if ($account->getMaxDeferFailMailPercentage() === -1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
346
            $params['max_defer_fail_percentage'] = "unlimited";
347
        } elseif ($account->getMaxDeferFailMailPercentage() > 0) {
348
            $params['max_defer_fail_percentage'] = intval($account->getMaxDeferFailMailPercentage());
349
        }
350
351
        ! empty($account->getUid()) ? $params['uid'] = $account->getUid() : null;
352
        ! empty($account->getPartition()) ? $params['homedir'] = $account->getPartition() : null;
353
        ! empty($options['dkim']) ? $params['dkim'] = intval($options['dkim']) : null;
354
        ! empty($options['spf']) ? $params['spf'] = intval($options['spf']) : null;
355
        ! empty($account->getOwner()) ? $params['owner'] = $account->getOwner() : null;
356
357
        $result = $this->client->sendRequest("/json-api/createacct", "GET", $params);
358
359
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
360
            throw new ClientExceptions($result['metadata']['reason']);
361
        }
362
363
        if ( ! empty($result) && ! empty($result['result'][0]) && $result['result'][0]['status'] === 0) {
364
            throw new ClientExceptions($result['result'][0]['statusmsg']);
365
        }
366
367
        if ( ! empty($result) && ! empty($result['result'][0]) && $result['result'][0]['status'] === 1) {
368
            return ['result' => $result['result'][0]['options'], 'raw_output' => $result['result'][0]['rawout']];
369
        }
370
371
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
372
            return ['result' => $result['data'], 'raw_output' => $result['metadata']['output']['raw']];
373
        }
374
375
        return [];
376
    }
377
378
    /**
379
     * This function retrieves domain data.
380
     *
381
     * WHM API function: Accounts -> domainuserdata
382
     *
383
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+domainuserdata
384
     *
385
     * @param $domain
386
     *
387
     * @return null|DomainUser
388
     * @throws ClientExceptions
389
     * @throws Exception
390
     */
391
    public function domainDetails($domain)
392
    {
393
        $params = ['domain' => $domain];
394
395
        $result = $this->client->sendRequest("/json-api/domainuserdata", "GET", $params);
396
        if (empty($result)) {
397
            return null;
398
        }
399
400
        if ($result['result'][0]['status'] === 0) {
401
            throw new ClientExceptions($result['result'][0]['statusmsg']);
402
        }
403
404
        $userData   = $result['userdata'];
405
        $domainUser = new DomainUser();
406
        $domainUser->setHasCGI((bool)$userData['hascgi']);
407
        $domainUser->setServerName($userData['servername']);
408
        $domainUser->setOwner($userData['owner']);
409
        $domainUser->setScriptAlias($userData['scriptalias']);
410
        $domainUser->setHomeDirectory($userData['homedir']);
411
        $domainUser->setCustomLog($userData['customlog']);
412
        $domainUser->setUser($userData['user']);
413
        $domainUser->setGroup($userData['group']);
414
        $domainUser->setIpAddress($userData['ip']);
415
        $domainUser->setPort($userData['port']);
416
        $domainUser->setPhpOpenBaseDirectoryProtect((bool)$userData['phpopenbasedirprotect']);
417
418
        if ($userData['usecanonicalname'] === "Off") {
419
            $domainUser->setUseCanonicalName(false);
420
        } elseif ($userData['usecanonicalname'] === "On") {
421
            $domainUser->setUseCanonicalName(true);
422
        }
423
424
        $domainUser->setServerAdmin($userData['serveradmin']);
425
        $domainUser->setServerAlias($userData['serveralias']);
426
        $domainUser->setDocumentRoot($userData['documentroot']);
427
428
        return $domainUser;
429
    }
430
431
    /**
432
     * This function modifies a user's disk quota.
433
     * WHM API function: Accounts -> editquota
434
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+editquota
435
     *
436
     * @param $username
437
     * @param $newQuota
438
     *
439
     * @return bool
440
     * @throws ClientExceptions
441
     * @throws Exception
442
     */
443
    public function changeDiskSpaceQuota($username, $newQuota)
444
    {
445
        $params = ['user' => $username, 'quota' => $newQuota];
446
447
        $this->client->sendRequest("/json-api/editquota", "GET", $params);
448
449
        return true;
450
    }
451
452
    /**
453
     * This function forces a user to change the account password after the next login attempt.
454
     *
455
     * WHM API function: Accounts -> forcepasswordchange
456
     *
457
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+forcepasswordchange
458
     *
459
     * @param array $usernames
460
     * @param int $stopOnFail
461
     *
462
     * @return null
463
     * @throws ClientExceptions
464
     * @throws Exception
465
     */
466
    public function forcePasswordChange(array $usernames, $stopOnFail = 1)
467
    {
468
        $params = [
469
            "stop_on_failure" => $stopOnFail
470
        ];
471
472
        $usersJson = [];
473
        foreach ($usernames as $username) {
474
            $usersJson[$username] = 1;
475
        }
476
477
        $params['users_json'] = json_encode($usersJson);
478
479
        $result = $this->client->sendRequest("/json-api/forcepasswordchange", "GET", $params);
480
        if ($result['metadata']['result'] === 0) {
481
            throw new ClientExceptions($result['metadata']['reason']);
482
        }
483
484
        if ( ! empty($result['data'])) {
485
            return $result['updated'];
486
        }
487
488
        return null;
489
    }
490
491
    /**
492
     * This function returns information about each domain on the server.
493
     *
494
     * WHM API function: Accounts -> get_domain_info
495
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+get_domain_info
496
     *
497
     * @return Domain[]|null
498
     * @throws ClientExceptions
499
     * @throws Exception
500
     */
501
    public function getDomains()
502
    {
503
        $params = [];
504
        $result = $this->client->sendRequest("/json-api/get_domain_info", "GET", $params);
505
506
        if (empty($result)) {
507
            return null;
508
        }
509
510
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
511
            $domains = $result['data']['domains'];
512
513
            $domainList = [];
514
            foreach ($domains as $domain) {
515
                $do = new Domain();
516
                $do->setPort(intval($domain['port']));
517
                $do->setUser($domain['user']);
518
                $do->setDomain($domain['domain']);
519
                $do->setIpv4SSL($domain['ipv4_ssl']);
520
                $do->setIpv6($domain['ipv6']);
521
                $do->setSslPort(intval($domain['port_ssl']));
522
                $do->setPhpVersion($domain['php_version']);
523
                $do->setUserOwner($domain['user_owner']);
524
                $do->setDomainType($domain['domain_type']);
525
                $do->setIpv6IsDedicated((bool)$domain['ipv6_is_dedicated']);
526
                $do->setIpv4($domain['ipv4']);
527
                $do->setModSecurityEnabled((bool)$domain['modsecurity_enabled']);
528
                $do->setDocRoot($domain['docroot']);
529
                $domainList[] = $do;
530
            }
531
532
            return $domainList;
533
        }
534
535
        return null;
536
    }
537
538
    /**
539
     * Digest Authentication is enabled or disabled for any specific user.
540
     * This function checks whether Digest Authentication is enabled for
541
     * a cPanel user.
542
     * Windows® Vista, Windows® 7, and Windows® 8 require Digest Authentication
543
     * support in order to access Web Disk over an unencrypted connection.
544
     *
545
     * WHM API function: Accounts -> has_digest_auth
546
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+has_digest_auth
547
     *
548
     * @param $user
549
     *
550
     * @return bool|null
551
     * @throws ClientExceptions
552
     * @throws Exception
553
     */
554 View Code Duplication
    public function hasDigestAuth($user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
555
    {
556
        $params = ['user' => $user];
557
        $result = $this->client->sendRequest("/json-api/has_digest_auth", "GET", $params);
558
        if ( ! empty($result['data'])) {
559
            return $result['data']['digestauth'] === 1 ? true : false;
560
        }
561
562
        return null;
563
    }
564
565
    /**
566
     * This function enables or disables Digest Authentication for an account.
567
     * Windows Vista®, Windows® 7, and Windows® 8 requires that
568
     * you enable Digest Authentication support in order to access your Web Disk over a clear text,
569
     * unencrypted connection.
570
     *
571
     * WHM API function: Accounts -> set_digest_auth
572
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+set_digest_auth
573
     *
574
     * @param $user
575
     * @param $password
576
     * @param bool $enableDigestAuth
577
     *
578
     * @return bool
579
     * @throws ClientExceptions
580
     * @throws Exception
581
     */
582
    public function setDigestAuth($user, $password, $enableDigestAuth = true)
583
    {
584
        $params = ['user' => $user, 'password' => $password, 'digestauth' => (int) $enableDigestAuth];
585
        $result = $this->client->sendRequest("/json-api/set_digest_auth", "GET", $params);
586
587
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
588
            throw new ClientExceptions($result['metadata']['reason']);
589
        }
590
591
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
592
            return true;
593
        }
594
595
        return false;
596
    }
597
598
    /**
599
     * This function checks whether a cPanel user's home directory contains a valid .my.cnf file.
600
     * WHM API function: Accounts -> has_mycnf_for_cpuser
601
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+has_mycnf_for_cpuser
602
     *
603
     * @param $user
604
     *
605
     * @return bool|null
606
     * @throws ClientExceptions
607
     * @throws Exception
608
     */
609 View Code Duplication
    public function hasMyCnfInHomeDirectory($user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
610
    {
611
        $params = ['user' => $user];
612
        $result = $this->client->sendRequest("/json-api/has_mycnf_for_cpuser", "GET", $params);
613
        if ( ! empty($result['data'])) {
614
            return $result['data']['has_mycnf_for_cpuser'] === 1 ? true : false;
615
        }
616
617
        return null;
618
    }
619
620
    /**
621
     * Modify a cPanel account's bandwidth quota.
622
     * WHM API function: Accounts -> limitbw
623
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+limitbw
624
     *
625
     * @param $user
626
     * @param $bwlimit
627
     *
628
     * @return null
629
     * @throws ClientExceptions
630
     * @throws Exception
631
     */
632 View Code Duplication
    public function limitBandwidth($user, $bwlimit)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
633
    {
634
        $params = ['user' => $user, 'bwlimit' => intval($bwlimit)];
635
        $result = $this->client->sendRequest("/json-api/limitbw", "GET", $params);
636
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
637
            return $result['data']['bwlimits'][0];
638
        }
639
640
        return null;
641
    }
642
643
644
    /**
645
     * Get lists of the cPanel user accounts and the root user on the server.
646
     * WHM API function: Accounts -> list_users
647
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+list_users
648
     *
649
     * @return array
650
     * @throws ClientExceptions
651
     * @throws Exception
652
     */
653 View Code Duplication
    public function getUsers()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
654
    {
655
        $result = $this->client->sendRequest("/json-api/list_users", "GET", []);
656
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
657
            return $result['data']['users'];
658
        }
659
660
        return [];
661
    }
662
663
    /**
664
     * Get a list of locked accounts.
665
     * This function lists locked accounts on the server. Only WHM users with root-level privileges can unsuspend locked accounts.
666
     *
667
     * WHM API function: Accounts -> listlockedaccounts
668
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listlockedaccounts
669
     *
670
     * @return array
671
     * @throws ClientExceptions
672
     * @throws Exception
673
     */
674 View Code Duplication
    public function getLockedAccounts()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
675
    {
676
        $result = $this->client->sendRequest("/json-api/listlockedaccounts", "GET", []);
677
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
678
            return $result['data']['account'];
679
        }
680
681
        return [];
682
    }
683
684
    /**
685
     * Get a list of suspended accounts
686
     *
687
     * WHM API function: listsuspended
688
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listsuspended
689
     *
690
     * @return SuspendedAccount[]
691
     * @throws ClientExceptions
692
     * @throws Exception
693
     */
694
    public function getSuspendedAccounts()
695
    {
696
        $result = $this->client->sendRequest("/json-api/listsuspended", "GET", []);
697
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
698
            $suspendList = $result['data']['account'];
699
700
            $lists = [];
701
            foreach ($suspendList as $item) {
702
                $sa = new SuspendedAccount();
703
                $sa->setUser($item['user']);
704
                $sa->setOwner($item['owner']);
705
                $sa->setIsLocked((bool)$item['is_locked']);
706
                $sa->setReason($item['reason']);
707
                $sa->setTime(DateTime::createFromFormat("D M j H:i:s Y", $item['time']));
0 ignored issues
show
Security Bug introduced by
It seems like \DateTime::createFromFor...:i:s Y', $item['time']) targeting DateTime::createFromFormat() can also be of type false; however, PreviewTechs\cPanelWHM\E...endedAccount::setTime() does only seem to accept object<DateTime>, did you maybe forget to handle an error condition?
Loading history...
708
                $lists[] = $sa;
709
            }
710
711
            return $lists;
712
        }
713
714
        return [];
715
    }
716
717
    /**
718
     * This function modifies a cPanel account.
719
     * You must define the user parameter to identify which account to update.
720
     * All other input parameters are optional, and assign new values to the account.
721
     * If you specify the current value in one of these parameters, no change will occur.
722
     *
723
     * WHM API function: Accounts -> modifyacct
724
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+modifyacct
725
     *
726
     * @param Account $account
727
     *
728
     * @return bool
729
     * @throws ClientExceptions
730
     * @throws Exception
731
     */
732
    public function modifyAccount(Account $account)
733
    {
734
        if(empty($account->getUser())){
735
            throw ClientExceptions::invalidArgument("You must provide username to modify account");
736
        }
737
738
        $params = [
739
            'user' => $account->getUser()
740
        ];
741
742
        if($account->isBackupEnabled()){
743
            $params['BACKUP'] = 1;
744
        }
745
746
        if($account->getBandwidthLimit() === -1){
747
            $params['BWLIMIT'] = "unlimited";
748
        }
749
750
        if(!empty($account->getDomain())){
751
            $params['DNS'] = $account->getDomain();
752
        }
753
754
        if(!empty($account->isCgiEnable())){
755
            $params['HASCGI'] = (int) $account->isCgiEnable();
756
        }
757
758
        if(!empty($account->getMaxAddonDomains())){
759
            $params['MAXADDON'] = $account->getMaxAddonDomains() === -1 ? "unlimited" : intval($account->getMaxAddonDomains());
760
        }
761
762
        if(!empty($account->getMaxFTP())){
763
            $params['MAXFTP'] = $account->getMaxFTP() === -1 ? "unlimited" : intval($account->getMaxFTP());
764
        }
765
766
        if(!empty($account->getMaxMailingList())){
767
            $params['MAXLST'] = $account->getMaxMailingList() === -1 ? "unlimited" : intval($account->getMaxMailingList());
768
        }
769
770
        if(!empty($account->getMaxParkedDomains())){
771
            $params['MAXPARK'] = $account->getMaxParkedDomains() === -1 ? "unlimited" : intval($account->getMaxParkedDomains());
772
        }
773
774
        if(!empty($account->getMaxPOP())){
775
            $params['MAXPOP'] = $account->getMaxPOP() === -1 ? "unlimited" : null;
776
        }
777
778
        if(!empty($account->getMaxSQL())){
779
            $params['MAXSQL'] = $account->getMaxSQL() === -1 ? "unlimited" : intval($account->getMaxSQL());
780
        }
781
782
        if(!empty($account->getMaxSubDomain())){
783
            $params['MAXSUB'] = $account->getMaxSubDomain() === -1 ? "unlimited" : intval($account->getMaxSubDomain());
784
        }
785
786
        if(!empty($account->getMaxEmailPerHour())){
787
            $params['MAX_EMAIL_PER_HOUR'] = $account->getMaxEmailPerHour() === -1 ? "unlimited" : intval($account->getMaxEmailPerHour());
788
        }
789
        if(!empty($account->getMaxEmailAccountQuota())){
790
            $params['MAX_EMAILACCT_QUOTA'] = $account->getMaxEmailAccountQuota() === -1 ? "unlimited" : intval($account->getMaxDeferFailMailPercentage());
791
        }
792
793
        if(!empty($account->getMaxDeferFailMailPercentage())){
794
            $params['MAX_DEFER_FAIL_PERCENTAGE'] = $account->getMaxDeferFailMailPercentage() === -1 ? "unlimited" : intval($account->getMaxDeferFailMailPercentage());
795
        }
796
797
        if(!empty($account->getOwner())){
798
            $params['owner'] = $account->getOwner();
799
        }
800
801
        if(!empty($account->getDiskLimit())){
802
            $params['QUOTA'] = $account->getDiskLimit() === -1 ? "unlimited" : intval($account->getDiskLimit());
803
        }
804
805
        if($account->isSpamAssassinEnable()){
806
            $params['spamassassin'] = (int) $account->isSpamAssassinEnable();
807
        }
808
809
        if($account->isFrontPageEnable()){
810
            $params['frontpage'] = (int) $account->isFrontPageEnable();
811
        }
812
813
        if(!empty($account->getTheme())){
814
            $params['RS'] = $account->getTheme();
815
        }
816
817
        if(!empty($account->getIpAddress())){
818
            $params['IP'] = $account->getIpAddress();
819
        }
820
821
        if(!empty($account->getLanguagePreference())){
822
            $params['LANG'] = $account->getLanguagePreference();
823
        }
824
825
        if(!empty($account->getMailboxFormat())){
826
            $params['MAILBOX_FORMAT'] = $account->getMailboxFormat();
827
        }
828
829
        if(is_bool($account->isOutgoingMailSuspended())){
830
            $params['OUTGOING_EMAIL_SUSPENDED'] = (int) $account->isOutgoingMailSuspended();
831
        }
832
833
        $result = $this->client->sendRequest("/json-api/modifyacct", "GET", $params);
834
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
835
            return true;
836
        }
837
838
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
839
            throw new ClientExceptions($result['metadata']['reason']);
840
        }
841
842
        return false;
843
    }
844
845
    /**
846
     * WHM API function: Accounts -> passwd
847
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+passwd
848
     *
849
     * @param $user
850
     * @param $newPassword
851
     * @param null $digestAuth
852
     * @param bool $dbPassUpdate
853
     *
854
     * @return null|array
855
     * @throws ClientExceptions
856
     * @throws Exception
857
     */
858
    public function changePassword($user, $newPassword, $digestAuth = null, $dbPassUpdate = false)
859
    {
860
        $params = [
861
            'user' => $user,
862
            'password' => $newPassword
863
        ];
864
865
        if(isset($digestAuth)){
866
            $params['digestauth'] = (int) $digestAuth;
867
        }
868
869
        if(isset($dbPassUpdate)){
870
            $params['db_pass_update'] = (int) $dbPassUpdate;
871
        }
872
873
        $result = $this->client->sendRequest("/json-api/passwd", "GET", $params);
874
875
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
876
            throw new ClientExceptions($result['metadata']['reason']);
877
        }
878
879
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
880
            return $result['data']['app'];
881
        }
882
883
        return null;
884
    }
885
886
    /**
887
     * This function deletes a cPanel or WHM account.
888
     *
889
     * WHM API function: Accounts -> removeacct
890
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+removeacct
891
     * @param $username
892
     * @param bool $keepDNS
893
     *
894
     * @return bool
895
     * @throws ClientExceptions
896
     * @throws Exception
897
     */
898 View Code Duplication
    public function remove($username, $keepDNS = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
899
    {
900
        $params = ['user' => $username, 'keepdns' => (int) $keepDNS];
901
        $result = $this->client->sendRequest("/json-api/removeacct", "GET", $params);
902
903
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
904
            throw new ClientExceptions($result['metadata']['reason']);
905
        }
906
907
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
908
            return true;
909
        }
910
911
        return false;
912
    }
913
914
    /**
915
     * This function retrieves account bandwidth information.
916
     * WHM API function: Accounts -> showbw
917
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+showbw
918
     *
919
     * @param null $month
920
     * @param null $year
921
     * @param null $resellerUsername
922
     * @param null $searchKeyword
923
     * @param null $searchType
924
     *
925
     * @return array
926
     * @throws ClientExceptions
927
     * @throws Exception
928
     */
929
    public function getBandwidthInfo($month = null, $year = null, $resellerUsername = null, $searchKeyword = null, $searchType = null)
930
    {
931
        $params = [];
932
        if(!empty($searchKeyword)){
933
            $params['search'] = $searchKeyword;
934
        }
935
936 View Code Duplication
        if(!empty($searchType) && !in_array($searchType, ["domain", "user", "owner", "ip", "package"])){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
937
            throw new ClientExceptions("searchType must be one of domain, user, owner, ip and package");
938
        }
939
940
        if(!empty($searchType)){
941
            $params['searchtype'] = $searchType;
942
        }
943
944
        if(!empty($month) && !is_int($month)){
945
            throw new ClientExceptions("month must be an integer");
946
        }
947
        if(!empty($month)){
948
            $params['month'] = intval($month);
949
        }
950
951
        if(!empty($year) && !is_int($year)){
952
            throw new ClientExceptions("year must be an integer");
953
        }
954
955
        if(!empty($year)){
956
            $params['year'] = intval($year);
957
        }
958
959
        if(!empty($resellerUsername)){
960
            $params['showres'] = $resellerUsername;
961
        }
962
963
        $result = $this->client->sendRequest("/json-api/showbw", "GET", $params);
964
965
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
966
            throw new ClientExceptions($result['metadata']['reason']);
967
        }
968
969
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1) {
970
            return $result['data']['acct'];
971
        }
972
973
        return [];
974
    }
975
976
    /**
977
     * This function suspends an account. Suspension denies the user access to the account. Unlike account deletion, you can reverse account suspension.
978
     * WHM API function: Accounts->suspendacct
979
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+suspendacct
980
     *
981
     * @param $user
982
     * @param $reason
983
     * @param bool $disallowUnsuspension
984
     *
985
     * @return bool
986
     * @throws ClientExceptions
987
     * @throws Exception
988
     */
989
    public function suspend($user, $reason, $disallowUnsuspension = true)
990
    {
991
        $params = ['user' => $user, 'reason' => $reason, 'disallowun' => (int) $disallowUnsuspension];
992
        $result = $this->client->sendRequest("/json-api/suspendacct", "GET", $params);
993
994
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
995
            throw new ClientExceptions($result['metadata']['reason']);
996
        }
997
998
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
999
            return true;
1000
        }
1001
1002
        return false;
1003
    }
1004
1005
    /**
1006
     * This function unsuspends an account.
1007
     * WHM API function: Accounts -> unsuspendacct
1008
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+unsuspendacct
1009
     *
1010
     * @param $user
1011
     *
1012
     * @return bool
1013
     * @throws ClientExceptions
1014
     * @throws Exception
1015
     */
1016 View Code Duplication
    public function unsuspend($user)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1017
    {
1018
        $params = ['user' => $user];
1019
        $result = $this->client->sendRequest("/json-api/unsuspendacct", "GET", $params);
1020
1021
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
1022
            throw new ClientExceptions($result['metadata']['reason']);
1023
        }
1024
1025
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
1026
            return true;
1027
        }
1028
1029
        return false;
1030
    }
1031
1032
    /**
1033
     * This function checks for username conflicts during account creation.
1034
     * WHM API function: verify_new_username
1035
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+verify_new_username
1036
     *
1037
     * @param $username
1038
     *
1039
     * @return bool
1040
     * @throws ClientExceptions
1041
     * @throws Exception
1042
     */
1043 View Code Duplication
    public function validateNewUsername($username)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1044
    {
1045
        $params = ['user' => $username];
1046
        $result = $this->client->sendRequest("/json-api/verify_new_username", "GET", $params);
1047
1048
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
1049
            throw new ClientExceptions($result['metadata']['reason']);
1050
        }
1051
1052
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
1053
            return true;
1054
        }
1055
    }
1056
1057
    /**
1058
     * This generates a URL for one-click login to cPanel.
1059
     *
1060
     * You can replace $service with a supported service, defaults to cPanel
1061
     * $app when set to something invalid will send the user to the cPanel home page, you
1062
     * can set it to anything valid to override the default of 'home'
1063
     *
1064
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+create_user_session
1065
     *
1066
     * @param $username
1067
     * @param string $service
1068
     * @param string $app
1069
     *
1070
     * @return mixed|\Psr\Http\Message\ResponseInterface
1071
     * @throws ClientExceptions
1072
     * @throws Exception
1073
     */
1074
    public function createUserSession($username, $service = 'cpaneld', $app = 'home')
1075
    {
1076
        $params = ['user' => $username, 'service' => $service, 'app' => $app];
1077
1078
        $result = $this->client->sendRequest('/json-api/create_user_session', 'GET', $params);
1079
1080
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
1081
            throw new ClientExceptions($result['metadata']['reason']);
1082
        }
1083
1084
        return $result;
1085
    }
1086
1087
    /**
1088
     * This changes the plan set on the account
1089
     *
1090
     * This is purely for changing the plan of the account
1091
     *
1092
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+modifyacct
1093
     *
1094
     * @param $username
1095
     * @param $plan
1096
     *
1097
     * @return mixed|\Psr\Http\Message\ResponseInterface
1098
     * @throws ClientExceptions
1099
     * @throws Exception
1100
     */
1101 View Code Duplication
    public function changePlan($username, $plan)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1102
    {
1103
        $params = ['user' => $username, 'pkg' => $plan];
1104
1105
        $result = $this->client->sendRequest('/json-api/changepackage', 'GET', $params);
1106
1107
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
1108
            throw new ClientExceptions($result['metadata']['reason']);
1109
        }
1110
1111
        return $result;
1112
    }
1113
}
1114