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 MediumPermission 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 MediumPermission, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class MediumPermission extends BasicPermission |
||
41 | { |
||
42 | /** |
||
43 | * Default data for new groups. |
||
44 | * |
||
45 | * @var array |
||
46 | */ |
||
47 | public $defaultGroupData = [ |
||
48 | 'name' => 'DEFAULT_GROUP', |
||
49 | 'description' => 'Short group description.', |
||
50 | 'auto_join' => false, |
||
51 | ]; |
||
52 | |||
53 | /** |
||
54 | * Constructor. |
||
55 | * |
||
56 | * @param Configuration $config |
||
57 | */ |
||
58 | public function __construct(Configuration $config) |
||
62 | |||
63 | /** |
||
64 | * Returns true if the group specified by $groupId owns the |
||
65 | * right given by $rightId, otherwise false. |
||
66 | * |
||
67 | * @param int $groupId Group ID |
||
68 | * @param int $rightId Right ID |
||
69 | * |
||
70 | * @return bool |
||
71 | */ |
||
72 | public function checkGroupRight($groupId, $rightId) |
||
106 | |||
107 | /** |
||
108 | * Returns an array that contains the right-IDs of all |
||
109 | * group-rights the group $groupId owns. |
||
110 | * |
||
111 | * @param int $groupId Group ID |
||
112 | * |
||
113 | * @return array |
||
114 | */ |
||
115 | View Code Duplication | public function getGroupRights($groupId) |
|
146 | |||
147 | /** |
||
148 | * Returns true, if the user given by $userId owns the right |
||
149 | * specified by $right. It does not matter if the user owns this |
||
150 | * right as a user-right or because of a group-membership. |
||
151 | * The parameter $right may be a right-ID (recommended for |
||
152 | * performance) or a right-name. |
||
153 | * |
||
154 | * @param int $userId Group ID |
||
155 | * @param mixed $right Rights |
||
156 | * |
||
157 | * @return bool |
||
158 | */ |
||
159 | View Code Duplication | public function checkRight($userId, $right) |
|
183 | |||
184 | /** |
||
185 | * Grants the group given by $groupId the right specified by |
||
186 | * $rightId. |
||
187 | * |
||
188 | * @param int $groupId Group ID |
||
189 | * @param int $rightId Right ID |
||
190 | * |
||
191 | * @return bool |
||
192 | */ |
||
193 | View Code Duplication | public function grantGroupRight($groupId, $rightId) |
|
225 | |||
226 | /** |
||
227 | * Refuses the group given by $groupId the right specified by |
||
228 | * $rightId. |
||
229 | * |
||
230 | * @param int $groupId Group ID |
||
231 | * @param int $rightId Right ID |
||
232 | * |
||
233 | * @return bool |
||
234 | */ |
||
235 | View Code Duplication | public function refuseGroupRight($groupId, $rightId) |
|
261 | |||
262 | /** |
||
263 | * Adds a new group to the database and returns the ID of the |
||
264 | * new group. The associative array $groupData contains the |
||
265 | * data for the new group. |
||
266 | * |
||
267 | * @param array $groupData Array of group data |
||
268 | * |
||
269 | * @return int |
||
270 | */ |
||
271 | View Code Duplication | public function addGroup(Array $groupData) |
|
300 | |||
301 | /** |
||
302 | * Changes the group data of the given group. |
||
303 | * |
||
304 | * @param int $groupId Group ID |
||
305 | * @param array $groupData Array of group data |
||
306 | * |
||
307 | * @return bool |
||
308 | */ |
||
309 | View Code Duplication | public function changeGroup($groupId, Array $groupData) |
|
340 | |||
341 | /** |
||
342 | * Removes the group given by $groupId from the database. |
||
343 | * Returns true on success, otherwise false. |
||
344 | * |
||
345 | * @param int $groupId Group ID |
||
346 | * |
||
347 | * @return bool |
||
348 | */ |
||
349 | View Code Duplication | public function deleteGroup($groupId) |
|
399 | |||
400 | /** |
||
401 | * Returns true if the user given by $userId is a member of |
||
402 | * the group specified by $groupId, otherwise false. |
||
403 | * |
||
404 | * @param int $userId User ID |
||
405 | * @param int $groupId Group ID |
||
406 | * |
||
407 | * @return bool |
||
408 | */ |
||
409 | View Code Duplication | public function isGroupMember($userId, $groupId) |
|
441 | |||
442 | /** |
||
443 | * Returns an array that contains the user-IDs of all members |
||
444 | * of the group $groupId. |
||
445 | * |
||
446 | * @param int $groupId Group ID |
||
447 | * |
||
448 | * @return array |
||
449 | */ |
||
450 | View Code Duplication | public function getGroupMembers($groupId) |
|
481 | |||
482 | /** |
||
483 | * Adds a new member $userId to the group $groupId. |
||
484 | * Returns true on success, otherwise false. |
||
485 | * |
||
486 | * @param int $userId User ID |
||
487 | * @param int $groupId Group ID |
||
488 | * |
||
489 | * @return bool |
||
490 | */ |
||
491 | View Code Duplication | public function addToGroup($userId, $groupId) |
|
520 | |||
521 | /** |
||
522 | * Removes a user $userId from the group $groupId. |
||
523 | * Returns true on success, otherwise false. |
||
524 | * |
||
525 | * @param int $userId User ID |
||
526 | * @param int $groupId Group ID |
||
527 | * |
||
528 | * @return bool |
||
529 | */ |
||
530 | View Code Duplication | public function removeFromGroup($userId, $groupId) |
|
553 | |||
554 | /** |
||
555 | * Returns the ID of the group that has the name $name. Returns |
||
556 | * 0 if the group-name cannot be found. |
||
557 | * |
||
558 | * @param string $name Group name |
||
559 | * |
||
560 | * @return int |
||
561 | */ |
||
562 | public function getGroupId($name) |
||
583 | |||
584 | /** |
||
585 | * Returns an associative array with the group-data of the group |
||
586 | * $groupId. |
||
587 | * |
||
588 | * @param int $groupId Group ID |
||
589 | * |
||
590 | * @return array |
||
591 | */ |
||
592 | public function getGroupData($groupId) |
||
619 | |||
620 | /** |
||
621 | * Returns an array that contains the IDs of all groups in which |
||
622 | * the user $userId is a member. |
||
623 | * |
||
624 | * @param int $userId User ID |
||
625 | * |
||
626 | * @return array |
||
627 | */ |
||
628 | public function getUserGroups($userId) |
||
659 | |||
660 | /** |
||
661 | * Returns an array with the IDs of all groups stored in the |
||
662 | * database if no user ID is passed. |
||
663 | * @param int userId |
||
664 | * @return array |
||
665 | */ |
||
666 | public function getAllGroups($userId = 1) |
||
699 | |||
700 | /** |
||
701 | * Get all groups in <option> tags. |
||
702 | * |
||
703 | * @todo Move into the Helper class |
||
704 | * |
||
705 | * @param array $groups Selected groups |
||
706 | * @param integer $userId |
||
707 | * @return string |
||
708 | */ |
||
709 | public function getAllGroupsOptions(Array $groups, $userId = 1) |
||
726 | |||
727 | /** |
||
728 | * Returns true if the user $userId owns the right $rightId |
||
729 | * because of a group-membership, otherwise false. |
||
730 | * |
||
731 | * @param int $userId User ID |
||
732 | * @param int $rightId Right ID |
||
733 | * |
||
734 | * @return bool |
||
735 | */ |
||
736 | View Code Duplication | public function checkUserGroupRight($userId, $rightId) |
|
775 | |||
776 | /** |
||
777 | * Checks the given associative array $groupData. If a |
||
778 | * parameter is incorrect or is missing, it will be replaced |
||
779 | * by the default values in $this->defaultGroupData. |
||
780 | * Returns the corrected $groupData associative array. |
||
781 | * |
||
782 | * @param array $groupData Array of group data |
||
783 | * |
||
784 | * @return array |
||
785 | */ |
||
786 | public function checkGroupData(Array $groupData) |
||
801 | |||
802 | /** |
||
803 | * Returns an array that contains the right-IDs of all rights |
||
804 | * the user $userId owns. User-rights and the rights the user |
||
805 | * owns because of a group-membership are taken into account. |
||
806 | * |
||
807 | * @param int $userId User ID |
||
808 | * |
||
809 | * @return array |
||
810 | */ |
||
811 | public function getAllUserRights($userId) |
||
821 | |||
822 | /** |
||
823 | * Adds the user $userId to all groups with the auto_join |
||
824 | * option. By using the auto_join option, user administration |
||
825 | * can be much easier. For example by setting this option only |
||
826 | * for a single group called 'All Users'. The autoJoin() method |
||
827 | * then has to be called every time a new user registers. |
||
828 | * Returns true on success, otherwise false. |
||
829 | * |
||
830 | * @param int $userId User ID |
||
831 | * |
||
832 | * @return bool |
||
833 | */ |
||
834 | public function autoJoin($userId) |
||
867 | |||
868 | /** |
||
869 | * Removes the user $userId from all groups. |
||
870 | * Returns true on success, otherwise false. |
||
871 | * |
||
872 | * @param int $userId User ID |
||
873 | * |
||
874 | * @return bool |
||
875 | */ |
||
876 | View Code Duplication | public function removeFromAllGroups($userId) |
|
897 | |||
898 | /** |
||
899 | * Returns an array that contains the IDs of all rights the user |
||
900 | * $userId owns because of a group-membership. |
||
901 | * |
||
902 | * @param int $userId User ID |
||
903 | * |
||
904 | * @return array |
||
905 | */ |
||
906 | View Code Duplication | public function getUserGroupRights($userId) |
|
942 | |||
943 | /** |
||
944 | * Refuses all group rights. |
||
945 | * Returns true on success, otherwise false. |
||
946 | * |
||
947 | * @param int $groupId Group ID |
||
948 | * |
||
949 | * @return bool |
||
950 | */ |
||
951 | View Code Duplication | public function refuseAllGroupRights($groupId) |
|
972 | |||
973 | /** |
||
974 | * Returns the name of the group $groupId. |
||
975 | * |
||
976 | * @param int $groupId Group ID |
||
977 | * |
||
978 | * @return string |
||
979 | */ |
||
980 | View Code Duplication | public function getGroupName($groupId) |
|
1005 | |||
1006 | /** |
||
1007 | * Removes all users from the group $groupId. |
||
1008 | * Returns true on success, otherwise false. |
||
1009 | * |
||
1010 | * @param int $groupId Group ID |
||
1011 | * |
||
1012 | * @return bool |
||
1013 | */ |
||
1014 | View Code Duplication | public function removeAllUsersFromGroup($groupId) |
|
1036 | } |
||
1037 |
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.