Passed
Push — master ( 1e2f79...ea4c5b )
by Shaharia
02:02
created

Accounts::changePassword()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 27

Duplication

Lines 6
Ratio 22.22 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 6
loc 27
c 0
b 0
f 0
ccs 0
cts 13
cp 0
rs 8.5546
cc 7
nc 12
nop 4
crap 56
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
        if ( ! empty($searchType) && ! in_array($searchType, ["domain", "owner", "user", "ip", "package"])) {
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
        if (empty($result)) {
166
            return null;
167
        }
168
169
        if ($result['status'] === 0) {
170
            throw ClientExceptions::recordNotFound(
171
                ! empty($result['statusmsg']) ? $result['statusmsg'] : "Record not found"
172
            );
173
        }
174
175
        if ( ! empty($result['acct']) && is_array($result['acct'])) {
176
            return Account::buildFromArray($result['acct'][0]);
177
        }
178
179
        return null;
180
    }
181
182
    /**
183
     * This function lists available WHM API 1 functions.
184
     *
185
     * This function only lists the functions that are available to the current user.
186
     * For example, if the authenticated user is a reseller without root -level privileges,
187
     * the function will not list WHM API 1 functions that require root privileges.
188
     *
189
     * WHM API function: Accounts -> applist
190
     *
191
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+applist
192
     *
193
     * @return array
194
     * @throws ClientExceptions
195
     * @throws Exception
196
     */
197
    public function availableFunctions()
198
    {
199
        $result = $this->client->sendRequest("/json-api/applist", 'GET', []);
200
201
        if ( ! empty($result['app']) && sizeof($result['app']) > 0) {
202
            return $result['app'];
203
        }
204
205
        return [];
206
    }
207
208
    /**
209
     * Create a new account. This function creates a cPanel account.
210
     * The function also sets up the new account's domain information.
211
     *
212
     * WHM API function: Accounts -> createacct
213
     *
214
     * @link    https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+createacct
215
     *
216
     * @param Account $account
217
     * @param array $options
218
     *
219
     * @return array
220
     * @throws ClientExceptions
221
     * @throws Exception
222
     */
223
    public function create(Account $account, array $options = [])
224
    {
225
        if (empty($account->getUser())) {
226
            throw ClientExceptions::invalidArgument("You must provide an username to create new account");
227
        }
228
229
        if (empty($account->getDomain())) {
230
            throw ClientExceptions::invalidArgument("You must provide a domain to create new account");
231
        }
232
233
        $params             = [];
234
        $params['username'] = $account->getUser();
235
        $params['domain']   = $account->getDomain();
236
        ! empty($account->getPlanName()) ? $params['plan'] = $account->getPlanName() : null;
237
        ! empty($options['pkgname']) ? $params['pkgname'] = $options['pkgname'] : null;
238
        if ( ! empty($options['savepkg'])) {
239
            if ( ! in_array(intval($options['savepkg']), [0, 1])) {
240
                throw new ClientExceptions("`savepkg` must be either 0 or 1");
241
            }
242
243
            $params['savepkg'] = $options['savepkg'];
244
        }
245
246
        ! empty($options['featurelist']) ? $params['featurelist'] = $options['featurelist'] : null;
247
        if ( ! empty($account->getDiskLimit())) {
248
            if ($account->getDiskLimit() === -1) {
249
                $params['quota'] = 0;
250
            } else {
251
                $params['quota'] = intval($account->getDiskLimit());
252
            }
253
        }
254
255
        ! empty($account->getPassword()) ? $params['password'] = $account->getPassword() : null;
256
        ! empty($account->getIpAddress()) ? $params['ip'] = $account->getIpAddress() : null;
257
        ! empty($account->isCgiEnable()) ? $params['cgi'] = (int)$account->isCgiEnable() : null;
258
        ! empty($account->isSpamAssassinEnable()) ?
259
            $params['spamassassin'] = (int)$account->isSpamAssassinEnable()
260
            : null;
261
        ! empty($account->isFrontPageEnable()) ? $params['frontpage'] = (int)$account->isFrontPageEnable() : null;
262
        ! empty($account->getShell()) ? $params['hasshell'] = 1 : null;
263
        ! empty($account->getEmail()) ? $params['contactemail'] = 1 : null;
264
        ! empty($account->getEmail()) ? $params['contactemail'] = 1 : 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 View Code Duplication
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
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...
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 View Code Duplication
        if ($result['metadata']['result'] === 0) {
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...
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 checks whether a cPanel user's home directory contains a valid .my.cnf file.
567
     * WHM API function: Accounts -> has_mycnf_for_cpuser
568
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+has_mycnf_for_cpuser
569
     *
570
     * @param $user
571
     *
572
     * @return bool|null
573
     * @throws ClientExceptions
574
     * @throws Exception
575
     */
576 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...
577
    {
578
        $params = ['user' => $user];
579
        $result = $this->client->sendRequest("/json-api/has_mycnf_for_cpuser", "GET", $params);
580
        if ( ! empty($result['data'])) {
581
            return $result['data']['has_mycnf_for_cpuser'] === 1 ? true : false;
582
        }
583
584
        return null;
585
    }
586
587
    /**
588
     * Modify a cPanel account's bandwidth quota.
589
     * WHM API function: Accounts -> limitbw
590
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+limitbw
591
     *
592
     * @param $user
593
     * @param $bwlimit
594
     *
595
     * @return null
596
     * @throws ClientExceptions
597
     * @throws Exception
598
     */
599
    public function limitBandwidth($user, $bwlimit)
600
    {
601
        $params = ['user' => $user, 'bwlimit' => intval($bwlimit)];
602
        $result = $this->client->sendRequest("/json-api/limitbw", "GET", $params);
603 View Code Duplication
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 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...
604
            return $result['data']['bwlimits'][0];
605
        }
606
607
        return null;
608
    }
609
610
611
    /**
612
     * Get lists of the cPanel user accounts and the root user on the server.
613
     * WHM API function: Accounts -> list_users
614
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+list_users
615
     *
616
     * @return array
617
     * @throws ClientExceptions
618
     * @throws Exception
619
     */
620 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...
621
    {
622
        $result = $this->client->sendRequest("/json-api/list_users", "GET", []);
623
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
624
            return $result['data']['users'];
625
        }
626
627
        return [];
628
    }
629
630
    /**
631
     * Get a list of locked accounts.
632
     * This function lists locked accounts on the server. Only WHM users with root-level privileges can unsuspend locked accounts.
633
     *
634
     * WHM API function: Accounts -> listlockedaccounts
635
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listlockedaccounts
636
     *
637
     * @return array
638
     * @throws ClientExceptions
639
     * @throws Exception
640
     */
641 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...
642
    {
643
        $result = $this->client->sendRequest("/json-api/listlockedaccounts", "GET", []);
644
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
645
            return $result['data']['account'];
646
        }
647
648
        return [];
649
    }
650
651
    /**
652
     * Get a list of suspended accounts
653
     *
654
     * WHM API function: listsuspended
655
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listsuspended
656
     *
657
     * @return SuspendedAccount[]
658
     * @throws ClientExceptions
659
     * @throws Exception
660
     */
661
    public function getSuspendedAccounts()
662
    {
663
        $result = $this->client->sendRequest("/json-api/listsuspended", "GET", []);
664
        if ( ! empty($result['metadata']) && $result['metadata']['result'] === 1) {
665
            $suspendList = $result['data']['account'];
666
667
            $lists = [];
668
            foreach ($suspendList as $item) {
669
                $sa = new SuspendedAccount();
670
                $sa->setUser($item['user']);
671
                $sa->setOwner($item['owner']);
672
                $sa->setIsLocked((bool)$item['is_locked']);
673
                $sa->setReason($item['reason']);
674
                $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...
675
                $lists[] = $sa;
676
            }
677
678
            return $lists;
679
        }
680
681
        return [];
682
    }
683
684
    /**
685
     * This function modifies a cPanel account.
686
     * You must define the user parameter to identify which account to update.
687
     * All other input parameters are optional, and assign new values to the account.
688
     * If you specify the current value in one of these parameters, no change will occur.
689
     *
690
     * WHM API function: Accounts -> modifyacct
691
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+modifyacct
692
     *
693
     * @param Account $account
694
     *
695
     * @return bool
696
     * @throws ClientExceptions
697
     * @throws Exception
698
     */
699
    public function modifyAccount(Account $account)
700
    {
701
        if(empty($account->getUser())){
702
            throw ClientExceptions::invalidArgument("You must provide username to modify account");
703
        }
704
705
        $params = [
706
            'user' => $account->getUser()
707
        ];
708
709
        if($account->isBackupEnabled()){
710
            $params['BACKUP'] = 1;
711
        }
712
713
        if($account->getBandwidthLimit() === -1){
714
            $params['BWLIMIT'] = "unlimited";
715
        }
716
717
        if(!empty($account->getDomain())){
718
            $params['DNS'] = $account->getDomain();
719
        }
720
721
        if(!empty($account->isCgiEnable())){
722
            $params['HASCGI'] = (int) $account->isCgiEnable();
723
        }
724
725
        if(!empty($account->getMaxAddonDomains())){
726
            $params['MAXADDON'] = $account->getMaxAddonDomains() === -1 ? "unlimited" : intval($account->getMaxAddonDomains());
727
        }
728
729
        if(!empty($account->getMaxFTP())){
730
            $params['MAXFTP'] = $account->getMaxFTP() === -1 ? "unlimited" : intval($account->getMaxFTP());
731
        }
732
733
        if(!empty($account->getMaxMailingList())){
734
            $params['MAXLST'] = $account->getMaxMailingList() === -1 ? "unlimited" : intval($account->getMaxMailingList());
735
        }
736
737
        if(!empty($account->getMaxParkedDomains())){
738
            $params['MAXPARK'] = $account->getMaxParkedDomains() === -1 ? "unlimited" : intval($account->getMaxParkedDomains());
739
        }
740
741
        if(!empty($account->getMaxPOP())){
742
            $params['MAXPOP'] = $account->getMaxPOP() === -1 ? "unlimited" : null;
743
        }
744
745
        if(!empty($account->getMaxSQL())){
746
            $params['MAXSQL'] = $account->getMaxSQL() === -1 ? "unlimited" : intval($account->getMaxSQL());
747
        }
748
749
        if(!empty($account->getMaxSubDomain())){
750
            $params['MAXSUB'] = $account->getMaxSubDomain() === -1 ? "unlimited" : intval($account->getMaxSubDomain());
751
        }
752
753
        if(!empty($account->getMaxEmailPerHour())){
754
            $params['MAX_EMAIL_PER_HOUR'] = $account->getMaxEmailPerHour() === -1 ? "unlimited" : intval($account->getMaxEmailPerHour());
755
        }
756
        if(!empty($account->getMaxEmailAccountQuota())){
757
            $params['MAX_EMAILACCT_QUOTA'] = $account->getMaxEmailAccountQuota() === -1 ? "unlimited" : intval($account->getMaxDeferFailMailPercentage());
758
        }
759
760
        if(!empty($account->getMaxDeferFailMailPercentage())){
761
            $params['MAX_DEFER_FAIL_PERCENTAGE'] = $account->getMaxDeferFailMailPercentage() === -1 ? "unlimited" : intval($account->getMaxDeferFailMailPercentage());
762
        }
763
764
        if(!empty($account->getOwner())){
765
            $params['owner'] = $account->getOwner();
766
        }
767
768
        if(!empty($account->getDiskLimit())){
769
            $params['QUOTA'] = $account->getDiskLimit() === -1 ? "unlimited" : intval($account->getDiskLimit());
770
        }
771
772
        if($account->isSpamAssassinEnable()){
773
            $params['spamassassin'] = (int) $account->isSpamAssassinEnable();
774
        }
775
776
        if($account->isFrontPageEnable()){
777
            $params['frontpage'] = (int) $account->isFrontPageEnable();
778
        }
779
780
        if(!empty($account->getTheme())){
781
            $params['RS'] = $account->getTheme();
782
        }
783
784
        if(!empty($account->getIpAddress())){
785
            $params['IP'] = $account->getIpAddress();
786
        }
787
788
        if(!empty($account->getLanguagePreference())){
789
            $params['LANG'] = $account->getLanguagePreference();
790
        }
791
792
        if(!empty($account->getMailboxFormat())){
793
            $params['MAILBOX_FORMAT'] = $account->getMailboxFormat();
794
        }
795
796
        if(is_bool($account->isOutgoingMailSuspended())){
797
            $params['OUTGOING_EMAIL_SUSPENDED'] = (int) $account->isOutgoingMailSuspended();
798
        }
799
800
        $result = $this->client->sendRequest("/json-api/modifyacct", "GET", $params);
801
        if(!empty($result['metadata']) && $result['metadata']['result'] === 1){
802
            return true;
803
        }
804
805 View Code Duplication
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
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...
806
            throw new ClientExceptions($result['metadata']['reason']);
807
        }
808
809
        return false;
810
    }
811
812
    /**
813
     * WHM API function: Accounts -> passwd
814
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+passwd
815
     *
816
     * @param $user
817
     * @param $newPassword
818
     * @param null $digestAuth
819
     * @param bool $dbPassUpdate
820
     *
821
     * @return null|array
822
     * @throws ClientExceptions
823
     * @throws Exception
824
     */
825
    public function changePassword($user, $newPassword, $digestAuth = null, $dbPassUpdate = false)
826
    {
827
        $params = [
828
            'user' => $user,
829
            'password' => $newPassword
830
        ];
831
832
        if(isset($digestAuth)){
833
            $params['digestauth'] = (int) $digestAuth;
834
        }
835
836
        if(isset($dbPassUpdate)){
837
            $params['db_pass_update'] = (int) $dbPassUpdate;
838
        }
839
840
        $result = $this->client->sendRequest("/json-api/passwd", "GET", $params);
841
842 View Code Duplication
        if(!empty($result['metadata']) && $result['metadata']['result'] === 0){
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...
843
            throw new ClientExceptions($result['metadata']['reason']);
844
        }
845
846 View Code Duplication
        if(!empty($result['metadata']) && $result['metadata']['result'] === 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...
847
            return $result['data']['app'];
848
        }
849
850
        return null;
851
    }
852
}
853