Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Accounts often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Accounts, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
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) |
||
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 = []) |
||
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) |
||
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() |
||
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 = []) |
||
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) |
||
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) |
||
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) |
||
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() |
||
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) |
|
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) |
|
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) |
||
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() |
|
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() |
|
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() |
||
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 | View Code Duplication | 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){ |
|
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) |
||
852 | |||
853 | /** |
||
854 | * This function deletes a cPanel or WHM account. |
||
855 | * |
||
856 | * WHM API function: Accounts -> removeacct |
||
857 | * @link https://documentation.cpanel.net/display/DD/WHM+API+1+Functions+-+removeacct |
||
858 | * @param $username |
||
859 | * @param bool $keepDNS |
||
860 | * |
||
861 | * @return bool |
||
862 | * @throws ClientExceptions |
||
863 | * @throws Exception |
||
864 | */ |
||
865 | public function remove($username, $keepDNS = false) |
||
880 | } |
||
881 |
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.