Passed
Push — master ( 9a8b65...622283 )
by Shaharia
02:47 queued 01:07
created

Accounts::forcePasswordChange()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 6
nop 2
dl 0
loc 23
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace PreviewTechs\cPanelWHM\WHM;
4
5
use Http\Client\Exception;
6
use PreviewTechs\cPanelWHM\Entity\Account;
7
use PreviewTechs\cPanelWHM\Entity\DomainUser;
8
use PreviewTechs\cPanelWHM\Exceptions\ClientExceptions;
9
use PreviewTechs\cPanelWHM\WHMClient;
10
11
/**
12
 * Class Accounts
13
 *
14
 * @package PreviewTechs\cPanelWHM\WHM
15
 */
16
class Accounts
17
{
18
    /**
19
     *
20
     * @var WHMClient
21
     */
22
    protected $client;
23
24
    /**
25
     * Accounts constructor.
26
     *
27
     * @param WHMClient $client
28
     */
29
    public function __construct(WHMClient $client)
30
    {
31
        $this->client = $client;
32
    }
33
34
    /**
35
     * Search accounts from your WHM server.
36
     *
37
     * WHM API function: Accounts -> listaccts
38
     *
39
     * $accounts = new Accounts($c);
40
     * $keyword = "search_keyword";
41
     * $searchType = "username";   //valid search types are "domain", "owner", "user", "ip", "package"
42
     * $options = [
43
     *       'searchmethod' => "exact",   //"exact" or "regex",
44
     *       "page" => 1,
45
     *       "limit" => 10,   //per page,
46
     *       "want" => "username"    //A comma-separated list of fields you want to fetch
47
     *   ];
48
     *
49
     * try {
50
     *       $accounts->searchAccounts($keyword, $searchType, $options);
51
     *   } catch (\Http\Client\Exception $e) {
52
     *       echo $e->getMessage();
53
     *   } catch (\PreviewTechs\cPanelWHM\Exceptions\ClientExceptions $e) {
54
     *       echo $e->getMessage();
55
     *   }
56
     *
57
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+listaccts
58
     *
59
     * @param null $keyword
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $keyword is correct as it would always require null to be passed?
Loading history...
60
     * @param null $searchType
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $searchType is correct as it would always require null to be passed?
Loading history...
61
     * @param array $options
62
     *
63
     * @return array
64
     * @throws ClientExceptions
65
     * @throws Exception
66
     */
67
    public function searchAccounts($keyword = null, $searchType = null, array $options = [])
68
    {
69
        $limit = 10;
70
        $page = 1;
71
72
        $params = [
73
            'api.version' => 1,
74
            'api.chunk.enable' => 1,
75
            'api.chunk.size' => $limit,
76
            'api.chunk.start' => $page * $limit
77
        ];
78
79
        if (!empty($options['limit'])) {
80
            $params['api.chunk.size'] = intval($options['limit']);
81
        }
82
83
        if (!empty($options['page'])) {
84
            $params['api.chunk.start'] = intval($options['page']) * $params['api.chunk.size'];
85
        }
86
87
        if (!empty($searchType) && !in_array($searchType, ["domain", "owner", "user", "ip", "package"])) {
88
            throw new \InvalidArgumentException("`searchType` must be one of these - domain, owner, user, ip, package");
89
        }
90
91
        if (!empty($options['searchmethod']) && !in_array($options['searchmethod'], ["exact", "regex"])) {
92
            throw new \InvalidArgumentException("options[searchmethod] must be either `regex` or `exact`");
93
        }
94
95
        if (!empty($options['want'])) {
96
            $params['want'] = $options['want'];
97
        }
98
99
        if (!empty($searchType)) {
100
            $params['searchtype'] = $searchType;
101
        }
102
103
        if (!empty($keyword)) {
104
            $params['search'] = $keyword;
105
            empty($searchType) ? $params['searchtype'] = "user" : null;
106
        }
107
108
        $results = $this->client->sendRequest("/json-api/listaccts", "GET", $params);
109
        if (empty($results['data']['acct'])) {
110
            return [];
111
        }
112
113
        $accounts = [];
114
        foreach ($results['data']['acct'] as $account) {
115
            $accounts[] = Account::buildFromArray($account);
116
        }
117
118
        return [
119
            'accounts' => $accounts,
120
            'count' => $params['api.chunk.size'],
121
            'page' => $page
122
        ];
123
    }
124
125
    /**
126
     * Get an account details
127
     *
128
     * WHM API function: Accounts -> accountsummary
129
     *
130
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+accountsummary
131
     *
132
     * @param null $user
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $user is correct as it would always require null to be passed?
Loading history...
133
     * @param null $domain
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $domain is correct as it would always require null to be passed?
Loading history...
134
     *
135
     * @return null|Account
136
     * @throws ClientExceptions
137
     * @throws Exception
138
     */
139
    public function getDetails($user = null, $domain = null)
140
    {
141
        if (empty($user) && empty($domain)) {
142
            throw ClientExceptions::invalidArgument("You must provide either a username or a domain or both");
143
        }
144
145
        if (!empty($user) && !empty($domain)) {
146
            throw ClientExceptions::invalidArgument(
147
                "You must provide only one argument either user OR domain (not both)"
148
            );
149
        }
150
151
        $params = [];
152
153
        if (!empty($user)) {
154
            $params['user'] = $user;
155
        }
156
157
        if (!empty($domain)) {
158
            $params['domain'] = $domain;
159
        }
160
161
        $result = $this->client->sendRequest("/json-api/accountsummary", "GET", $params);
162
        if (empty($result)) {
163
            return null;
164
        }
165
166
        if ($result['status'] === 0) {
167
            throw ClientExceptions::recordNotFound(
168
                !empty($result['statusmsg']) ? $result['statusmsg'] : "Record not found"
169
            );
170
        }
171
172
        if (!empty($result['acct']) && is_array($result['acct'])) {
173
            return Account::buildFromArray($result['acct'][0]);
174
        }
175
176
        return null;
177
    }
178
179
    /**
180
     * This function lists available WHM API 1 functions.
181
     *
182
     * This function only lists the functions that are available to the current user.
183
     * For example, if the authenticated user is a reseller without root -level privileges,
184
     * the function will not list WHM API 1 functions that require root privileges.
185
     *
186
     * WHM API function: Accounts -> applist
187
     *
188
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+applist
189
     *
190
     * @return array
191
     * @throws ClientExceptions
192
     * @throws Exception
193
     */
194
    public function availableFunctions()
195
    {
196
        $result = $this->client->sendRequest("/json-api/applist", 'GET', []);
197
198
        if (!empty($result['app']) && sizeof($result['app']) > 0) {
199
            return $result['app'];
200
        }
201
202
        return [];
203
    }
204
205
    /**
206
     * Create a new account. This function creates a cPanel account.
207
     * The function also sets up the new account's domain information.
208
     *
209
     * WHM API function: Accounts -> createacct
210
     *
211
     * @link    https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+createacct
212
     *
213
     * @param Account $account
214
     * @param array $options
215
     * @return array
216
     * @throws ClientExceptions
217
     * @throws Exception
218
     */
219
    public function create(Account $account, array $options = [])
220
    {
221
        if (empty($account->getUser())) {
222
            throw ClientExceptions::invalidArgument("You must provide an username to create new account");
223
        }
224
225
        if (empty($account->getDomain())) {
226
            throw ClientExceptions::invalidArgument("You must provide a domain to create new account");
227
        }
228
229
        $params = [];
230
        $params['username'] = $account->getUser();
231
        $params['domain'] = $account->getDomain();
232
        !empty($account->getPlanName()) ? $params['plan'] = $account->getPlanName() : null;
233
        !empty($options['pkgname']) ? $params['pkgname'] = $options['pkgname'] : null;
234
        if (!empty($options['savepkg'])) {
235
            if (!in_array(intval($options['savepkg']), [0, 1])) {
236
                throw new ClientExceptions("`savepkg` must be either 0 or 1");
237
            }
238
239
            $params['savepkg'] = $options['savepkg'];
240
        }
241
242
        !empty($options['featurelist']) ? $params['featurelist'] = $options['featurelist'] : null;
243
        if (!empty($account->getDiskLimit())) {
244
            if ($account->getDiskLimit() === -1) {
245
                $params['quota'] = 0;
246
            } else {
247
                $params['quota'] = intval($account->getDiskLimit());
248
            }
249
        }
250
251
        !empty($account->getPassword()) ? $params['password'] = $account->getPassword() : null;
252
        !empty($account->getIpAddress()) ? $params['ip'] = $account->getIpAddress() : null;
253
        !empty($account->isCgiEnable()) ? $params['cgi'] = (int)$account->isCgiEnable() : null;
254
        !empty($account->isSpamAssassinEnable()) ?
255
            $params['spamassassin'] = (int)$account->isSpamAssassinEnable()
256
            : null;
257
        !empty($account->isFrontPageEnable()) ? $params['frontpage'] = (int)$account->isFrontPageEnable() : null;
258
        !empty($account->getShell()) ? $params['hasshell'] = 1 : null;
259
        !empty($account->getEmail()) ? $params['contactemail'] = 1 : null;
260
        !empty($account->getEmail()) ? $params['contactemail'] = 1 : null;
261
        !empty($account->getTheme()) ? $params['cpmod'] = 1 : null;
262
263
        if ($account->getMaxFTP() === -1) {
264
            $params['maxftp'] = "unlimited";
265
        } elseif ($account->getMaxFTP() > 0) {
266
            $params['maxftp'] = intval($account->getMaxFTP());
267
        }
268
269
        if ($account->getMaxSQL() === -1) {
270
            $params['maxsql'] = "unlimited";
271
        } elseif ($account->getMaxSQL() > 0) {
272
            $params['maxsql'] = intval($account->getMaxSQL());
273
        }
274
275
        if ($account->getMaxPOP() === -1) {
276
            $params['maxpop'] = "unlimited";
277
        } elseif ($account->getMaxPOP() > 0) {
278
            $params['maxpop'] = intval($account->getMaxPOP());
279
        }
280
281
        if ($account->getMaxMailingList() === -1) {
282
            $params['maxlst'] = "unlimited";
283
        } elseif ($account->getMaxMailingList() > 0) {
284
            $params['maxlst'] = intval($account->getMaxMailingList());
285
        }
286
287
        if ($account->getMaxSubDomain() === -1) {
288
            $params['maxsub'] = "unlimited";
289
        } elseif ($account->getMaxSubDomain() > 0) {
290
            $params['maxsub'] = intval($account->getMaxSubDomain());
291
        }
292
293
        if ($account->getMaxParkedDomains() === -1) {
294
            $params['maxpark'] = "unlimited";
295
        } elseif ($account->getMaxParkedDomains() > 0) {
296
            $params['maxpark'] = intval($account->getMaxParkedDomains());
297
        }
298
299
        if ($account->getMaxAddonDomains() === -1) {
300
            $params['maxaddon'] = "unlimited";
301
        } elseif ($account->getMaxAddonDomains() > 0) {
302
            $params['maxaddon'] = intval($account->getMaxAddonDomains());
303
        }
304
305
        if ($account->getBandwidthLimit() === -1) {
306
            $params['bwlimit'] = "unlimited";
307
        } elseif ($account->getBandwidthLimit() > 0) {
308
            $params['bwlimit'] = intval($account->getBandwidthLimit());
309
        }
310
311
        !empty($options['customip']) ? $params['customip'] = $options['customip'] : null;
312
313
        !empty($account->getLanguagePreference()) ? $params['language'] = $account->getLanguagePreference() : null;
314
315
        !empty($options['useregns']) ? $params['useregns'] = $options['useregns'] : null;
316
        !empty($options['reseller']) ? $params['reseller'] = (int)$options['reseller'] : null;
317
        !empty($options['forcedns']) ? $params['forcedns'] = (int)$options['forcedns'] : null;
318
319
        !empty($account->getMailboxFormat()) ? $params['mailbox_format'] = $account->getMailboxFormat() : null;
320
321
        if (!empty($options['mxcheck'])) {
322
            if (!in_array($options['mxcheck'], ['local', 'secondary', 'remote', 'auto'])) {
323
                throw new ClientExceptions("options[mxcheck] parameters must be one of local, secondary, remote, auto");
324
            }
325
326
            $params['mxcheck'] = $options['mxcheck'];
327
        }
328
329
        if ($account->getMaxEmailPerHour() === -1) {
330
            $params['max_email_per_hour'] = "unlimited";
331
        } elseif ($account->getMaxEmailPerHour() > 0) {
332
            $params['max_email_per_hour'] = intval($account->getMaxEmailPerHour());
333
        }
334
335
        if ($account->getMaxEmailAccountQuota() === -1) {
336
            $params['max_emailacct_quota'] = "unlimited";
337
        } elseif ($account->getMaxEmailAccountQuota() > 0) {
338
            $params['max_email_per_hour'] = intval($account->getMaxEmailAccountQuota());
339
        }
340
341
        if ($account->getMaxDeferFailMailPercentage() === -1) {
342
            $params['max_defer_fail_percentage'] = "unlimited";
343
        } elseif ($account->getMaxDeferFailMailPercentage() > 0) {
344
            $params['max_defer_fail_percentage'] = intval($account->getMaxDeferFailMailPercentage());
345
        }
346
347
        !empty($account->getUid()) ? $params['uid'] = $account->getUid() : null;
348
        !empty($account->getPartition()) ? $params['homedir'] = $account->getPartition() : null;
349
        !empty($options['dkim']) ? $params['dkim'] = intval($options['dkim']) : null;
350
        !empty($options['spf']) ? $params['spf'] = intval($options['spf']) : null;
351
        !empty($account->getOwner()) ? $params['owner'] = $account->getOwner() : null;
352
353
        $result = $this->client->sendRequest("/json-api/createacct", "GET", $params);
354
355
        if (!empty($result) && !empty($result['result'][0]) && $result['result'][0]['status'] === 0) {
356
            throw new ClientExceptions($result['result'][0]['statusmsg']);
357
        }
358
359
        if (!empty($result) && !empty($result['result'][0]) && $result['result'][0]['status'] === 1) {
360
            return ['result' => $result['result'][0]['options'], 'raw_output' => $result['result'][0]['rawout']];
361
        }
362
363
        return [];
364
    }
365
366
    /**
367
     * This function retrieves domain data.
368
     *
369
     * WHM API function: Accounts -> domainuserdata
370
     *
371
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+domainuserdata
372
     * @param $domain
373
     * @return null|DomainUser
374
     * @throws ClientExceptions
375
     * @throws Exception
376
     */
377
    public function domainDetails($domain)
378
    {
379
        $params = ['domain' => $domain];
380
381
        $result = $this->client->sendRequest("/json-api/domainuserdata", "GET", $params);
382
        if(empty($result)){
383
            return null;
384
        }
385
386
        if($result['result'][0]['status'] === 0){
387
            throw new ClientExceptions($result['result'][0]['statusmsg']);
388
        }
389
390
        $userData = $result['userdata'];
391
        $domainUser = new DomainUser();
392
        $domainUser->setHasCGI((bool) $userData['hascgi']);
393
        $domainUser->setServerName($userData['servername']);
394
        $domainUser->setOwner($userData['owner']);
395
        $domainUser->setScriptAlias($userData['scriptalias']);
396
        $domainUser->setHomeDirectory($userData['homedir']);
397
        $domainUser->setCustomLog($userData['customlog']);
398
        $domainUser->setUser($userData['user']);
399
        $domainUser->setGroup($userData['group']);
400
        $domainUser->setIpAddress($userData['ip']);
401
        $domainUser->setPort($userData['port']);
402
        $domainUser->setPhpOpenBaseDirectoryProtect((bool) $userData['phpopenbasedirprotect']);
403
404
        if($userData['usecanonicalname'] === "Off"){
405
            $domainUser->setUseCanonicalName(false);
406
        }elseif($userData['usecanonicalname'] === "On"){
407
            $domainUser->setUseCanonicalName(true);
408
        }
409
410
        $domainUser->setServerAdmin($userData['serveradmin']);
411
        $domainUser->setServerAlias($userData['serveralias']);
412
        $domainUser->setDocumentRoot($userData['documentroot']);
413
414
        return $domainUser;
415
    }
416
417
    /**
418
     * This function modifies a user's disk quota.
419
     * WHM API function: Accounts -> editquota
420
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+editquota
421
     *
422
     * @param $username
423
     * @param $newQuota
424
     * @return bool
425
     * @throws ClientExceptions
426
     * @throws Exception
427
     */
428
    public function changeDiskSpaceQuota($username, $newQuota)
429
    {
430
        $params = ['user' => $username, 'quota' => $newQuota];
431
432
        $this->client->sendRequest("/json-api/editquota", "GET", $params);
433
        return true;
434
    }
435
436
    /**
437
     * This function forces a user to change the account password after the next login attempt.
438
     *
439
     * WHM API function: Accounts -> forcepasswordchange
440
     *
441
     * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+forcepasswordchange
442
     *
443
     * @param array $usernames
444
     * @param int $stopOnFail
445
     * @return null
446
     * @throws ClientExceptions
447
     * @throws Exception
448
     */
449
    public function forcePasswordChange(array $usernames, $stopOnFail = 1)
450
    {
451
        $params = [
452
            "stop_on_failure" => $stopOnFail
453
        ];
454
455
        $usersJson = [];
456
        foreach ($usernames as $username){
457
            $usersJson[$username] = 1;
458
        }
459
460
        $params['users_json'] = json_encode($usersJson);
461
462
        $result = $this->client->sendRequest("/json-api/forcepasswordchange", "GET", $params);
463
        if($result['metadata']['result'] === 0){
464
            throw new ClientExceptions($result['metadata']['reason']);
465
        }
466
467
        if(!empty($result['data'])){
468
            return $result['updated'];
469
        }
470
471
        return null;
472
    }
473
}
474