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 Handler 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 Handler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
27 | class Handler implements BaseUserHandler |
||
28 | { |
||
29 | /** |
||
30 | * Gateway for storing user data. |
||
31 | * |
||
32 | * @var \eZ\Publish\Core\Persistence\Legacy\User\Gateway |
||
33 | */ |
||
34 | protected $userGateway; |
||
35 | |||
36 | /** |
||
37 | * Gateway for storing role data. |
||
38 | * |
||
39 | * @var \eZ\Publish\Core\Persistence\Legacy\User\Role\Gateway |
||
40 | */ |
||
41 | protected $roleGateway; |
||
42 | |||
43 | /** |
||
44 | * Mapper for user related objects. |
||
45 | * |
||
46 | * @var \eZ\Publish\Core\Persistence\Legacy\User\Mapper |
||
47 | */ |
||
48 | protected $mapper; |
||
49 | |||
50 | /** @var \eZ\Publish\Core\Persistence\Legacy\User\Role\LimitationConverter */ |
||
51 | protected $limitationConverter; |
||
52 | |||
53 | /** |
||
54 | * Construct from userGateway. |
||
55 | * |
||
56 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Gateway $userGateway |
||
57 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Role\Gateway $roleGateway |
||
58 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Mapper $mapper |
||
59 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Role\LimitationConverter $limitationConverter |
||
60 | */ |
||
61 | public function __construct(Gateway $userGateway, RoleGateway $roleGateway, Mapper $mapper, LimitationConverter $limitationConverter) |
||
68 | |||
69 | /** |
||
70 | * Create a user. |
||
71 | * |
||
72 | * The User struct used to create the user will contain an ID which is used |
||
73 | * to reference the user. |
||
74 | * |
||
75 | * @param \eZ\Publish\SPI\Persistence\User $user |
||
76 | * |
||
77 | * @return \eZ\Publish\SPI\Persistence\User |
||
78 | */ |
||
79 | public function create(User $user) |
||
85 | |||
86 | /** |
||
87 | * Loads user with user ID. |
||
88 | * |
||
89 | * @param mixed $userId |
||
90 | * |
||
91 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
92 | * |
||
93 | * @return \eZ\Publish\SPI\Persistence\User |
||
94 | */ |
||
95 | View Code Duplication | public function load($userId) |
|
105 | |||
106 | /** |
||
107 | * Loads user with user login. |
||
108 | * |
||
109 | * @param string $login |
||
110 | * |
||
111 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
112 | * |
||
113 | * @return \eZ\Publish\SPI\Persistence\User |
||
114 | */ |
||
115 | public function loadByLogin($login) |
||
127 | |||
128 | /** |
||
129 | * Loads user(s) with user email. |
||
130 | * |
||
131 | * As earlier eZ Publish versions supported several users having same email (ini config), |
||
132 | * this function may return several users. |
||
133 | * |
||
134 | * @param string $email |
||
135 | * |
||
136 | * @return \eZ\Publish\SPI\Persistence\User[] |
||
137 | */ |
||
138 | public function loadByEmail($email) |
||
148 | |||
149 | /** |
||
150 | * Loads user with user hash. |
||
151 | * |
||
152 | * @param string $hash |
||
153 | * |
||
154 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
155 | * |
||
156 | * @return \eZ\Publish\SPI\Persistence\User |
||
157 | */ |
||
158 | View Code Duplication | public function loadUserByToken($hash) |
|
168 | |||
169 | /** |
||
170 | * Update the user information specified by the user struct. |
||
171 | * |
||
172 | * @param \eZ\Publish\SPI\Persistence\User $user |
||
173 | */ |
||
174 | public function update(User $user) |
||
178 | |||
179 | /** |
||
180 | * Update the user token information specified by the userToken struct. |
||
181 | * |
||
182 | * @param \eZ\Publish\SPI\Persistence\User\UserTokenUpdateStruct $userTokenUpdateStruct |
||
183 | */ |
||
184 | public function updateUserToken(UserTokenUpdateStruct $userTokenUpdateStruct) |
||
188 | |||
189 | /** |
||
190 | * Expires user account key with user hash. |
||
191 | * |
||
192 | * @param string $hash |
||
193 | */ |
||
194 | public function expireUserToken($hash) |
||
198 | |||
199 | /** |
||
200 | * Delete user with the given ID. |
||
201 | * |
||
202 | * @param mixed $userId |
||
203 | */ |
||
204 | public function delete($userId) |
||
208 | |||
209 | /** |
||
210 | * Create new role draft. |
||
211 | * |
||
212 | * Sets status to Role::STATUS_DRAFT on the new returned draft. |
||
213 | * |
||
214 | * @param \eZ\Publish\SPI\Persistence\User\RoleCreateStruct $createStruct |
||
215 | * |
||
216 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
217 | */ |
||
218 | public function createRole(RoleCreateStruct $createStruct) |
||
222 | |||
223 | /** |
||
224 | * Creates a draft of existing defined role. |
||
225 | * |
||
226 | * Sets status to Role::STATUS_DRAFT on the new returned draft. |
||
227 | * |
||
228 | * @param mixed $roleId |
||
229 | * |
||
230 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role with defined status is not found |
||
231 | * |
||
232 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
233 | */ |
||
234 | public function createRoleDraft($roleId) |
||
242 | |||
243 | /** |
||
244 | * Internal method for creating Role. |
||
245 | * |
||
246 | * Used by self::createRole() and self::createRoleDraft() |
||
247 | * |
||
248 | * @param \eZ\Publish\SPI\Persistence\User\RoleCreateStruct $createStruct |
||
249 | * @param mixed|null $roleId Used by self::createRoleDraft() to retain Role id in the draft |
||
250 | * |
||
251 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
252 | */ |
||
253 | protected function internalCreateRole(RoleCreateStruct $createStruct, $roleId = null) |
||
270 | |||
271 | /** |
||
272 | * Copies an existing role. |
||
273 | * |
||
274 | * @param \eZ\Publish\SPI\Persistence\User\RoleCopyStruct $copyStruct |
||
275 | * |
||
276 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
277 | */ |
||
278 | public function copyRole(User\RoleCopyStruct $copyStruct) |
||
292 | |||
293 | /** |
||
294 | * Loads a specified role (draft) by $roleId and $status. |
||
295 | * |
||
296 | * @param mixed $roleId |
||
297 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
298 | * |
||
299 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role with given status does not exist |
||
300 | * |
||
301 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
302 | */ |
||
303 | View Code Duplication | public function loadRole($roleId, $status = Role::STATUS_DEFINED) |
|
318 | |||
319 | /** |
||
320 | * Loads a specified role (draft) by $identifier and $status. |
||
321 | * |
||
322 | * @param string $identifier |
||
323 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
324 | * |
||
325 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role is not found |
||
326 | * |
||
327 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
328 | */ |
||
329 | View Code Duplication | public function loadRoleByIdentifier($identifier, $status = Role::STATUS_DEFINED) |
|
344 | |||
345 | /** |
||
346 | * Loads a role draft by the original role ID. |
||
347 | * |
||
348 | * @param mixed $roleId ID of the role the draft was created from. |
||
349 | * |
||
350 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role is not found |
||
351 | * |
||
352 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
353 | */ |
||
354 | View Code Duplication | public function loadRoleDraftByRoleId($roleId) |
|
369 | |||
370 | /** |
||
371 | * Loads all roles. |
||
372 | * |
||
373 | * @return \eZ\Publish\SPI\Persistence\User\Role[] |
||
374 | */ |
||
375 | View Code Duplication | public function loadRoles() |
|
388 | |||
389 | /** |
||
390 | * Update role (draft). |
||
391 | * |
||
392 | * @param \eZ\Publish\SPI\Persistence\User\RoleUpdateStruct $role |
||
393 | */ |
||
394 | public function updateRole(RoleUpdateStruct $role) |
||
398 | |||
399 | /** |
||
400 | * Delete the specified role (draft). |
||
401 | * |
||
402 | * @param mixed $roleId |
||
403 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
404 | */ |
||
405 | public function deleteRole($roleId, $status = Role::STATUS_DEFINED) |
||
415 | |||
416 | /** |
||
417 | * Publish the specified role draft. |
||
418 | * |
||
419 | * @param mixed $roleDraftId |
||
420 | */ |
||
421 | public function publishRoleDraft($roleDraftId) |
||
448 | |||
449 | /** |
||
450 | * Adds a policy to a role draft. |
||
451 | * |
||
452 | * @param mixed $roleId |
||
453 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
454 | * |
||
455 | * @return \eZ\Publish\SPI\Persistence\User\Policy |
||
456 | */ |
||
457 | public function addPolicyByRoleDraft($roleId, Policy $policy) |
||
470 | |||
471 | /** |
||
472 | * Adds a policy to a role. |
||
473 | * |
||
474 | * @param mixed $roleId |
||
475 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
476 | * |
||
477 | * @return \eZ\Publish\SPI\Persistence\User\Policy |
||
478 | */ |
||
479 | public function addPolicy($roleId, Policy $policy) |
||
490 | |||
491 | /** |
||
492 | * Update a policy. |
||
493 | * |
||
494 | * Replaces limitations values with new values. |
||
495 | * |
||
496 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
497 | */ |
||
498 | public function updatePolicy(Policy $policy) |
||
506 | |||
507 | /** |
||
508 | * Removes a policy from a role. |
||
509 | * |
||
510 | * @param mixed $policyId |
||
511 | * @param mixed $roleId |
||
512 | */ |
||
513 | public function deletePolicy($policyId, $roleId) |
||
520 | |||
521 | /** |
||
522 | * Returns the user policies associated with the user (including inherited policies from user groups). |
||
523 | * |
||
524 | * @param mixed $userId |
||
525 | * |
||
526 | * @return \eZ\Publish\SPI\Persistence\User\Policy[] |
||
527 | */ |
||
528 | View Code Duplication | public function loadPoliciesByUserId($userId) |
|
540 | |||
541 | /** |
||
542 | * Assigns role to a user or user group with given limitations. |
||
543 | * |
||
544 | * The limitation array looks like: |
||
545 | * <code> |
||
546 | * array( |
||
547 | * 'Subtree' => array( |
||
548 | * '/1/2/', |
||
549 | * '/1/4/', |
||
550 | * ), |
||
551 | * 'Foo' => array( 'Bar' ), |
||
552 | * … |
||
553 | * ) |
||
554 | * </code> |
||
555 | * |
||
556 | * Where the keys are the limitation identifiers, and the respective values |
||
557 | * are an array of limitation values. The limitation parameter is optional. |
||
558 | * |
||
559 | * @param mixed $contentId The groupId or userId to assign the role to. |
||
560 | * @param mixed $roleId |
||
561 | * @param array $limitation |
||
562 | */ |
||
563 | public function assignRole($contentId, $roleId, array $limitation = null) |
||
568 | |||
569 | /** |
||
570 | * Un-assign a role. |
||
571 | * |
||
572 | * @param mixed $contentId The user or user group Id to un-assign the role from. |
||
573 | * @param mixed $roleId |
||
574 | */ |
||
575 | public function unassignRole($contentId, $roleId) |
||
579 | |||
580 | /** |
||
581 | * Un-assign a role by assignment ID. |
||
582 | * |
||
583 | * @param mixed $roleAssignmentId The assignment ID. |
||
584 | */ |
||
585 | public function removeRoleAssignment($roleAssignmentId) |
||
589 | |||
590 | /** |
||
591 | * Loads role assignment for specified assignment ID. |
||
592 | * |
||
593 | * @param mixed $roleAssignmentId |
||
594 | * |
||
595 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role assignment is not found |
||
596 | * |
||
597 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment |
||
598 | */ |
||
599 | public function loadRoleAssignment($roleAssignmentId) |
||
609 | |||
610 | /** |
||
611 | * Loads roles assignments Role. |
||
612 | * |
||
613 | * Role Assignments with same roleId and limitationIdentifier will be merged together into one. |
||
614 | * |
||
615 | * @param mixed $roleId |
||
616 | * |
||
617 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment[] |
||
618 | */ |
||
619 | View Code Duplication | public function loadRoleAssignmentsByRoleId($roleId) |
|
629 | |||
630 | /** |
||
631 | * Loads roles assignments to a user/group. |
||
632 | * |
||
633 | * Role Assignments with same roleId and limitationIdentifier will be merged together into one. |
||
634 | * |
||
635 | * @param mixed $groupId In legacy storage engine this is the content object id roles are assigned to in ezuser_role. |
||
636 | * By the nature of legacy this can currently also be used to get by $userId. |
||
637 | * @param bool $inherit If true also return inherited role assignments from user groups. |
||
638 | * |
||
639 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment[] |
||
640 | */ |
||
641 | View Code Duplication | public function loadRoleAssignmentsByGroupId($groupId, $inherit = false) |
|
651 | } |
||
652 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.