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 | /** |
||
51 | * @var \eZ\Publish\Core\Persistence\Legacy\User\Role\LimitationConverter |
||
52 | */ |
||
53 | protected $limitationConverter; |
||
54 | |||
55 | /** |
||
56 | * Construct from userGateway. |
||
57 | * |
||
58 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Gateway $userGateway |
||
59 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Role\Gateway $roleGateway |
||
60 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Mapper $mapper |
||
61 | * @param \eZ\Publish\Core\Persistence\Legacy\User\Role\LimitationConverter $limitationConverter |
||
62 | */ |
||
63 | public function __construct(Gateway $userGateway, RoleGateway $roleGateway, Mapper $mapper, LimitationConverter $limitationConverter) |
||
70 | |||
71 | /** |
||
72 | * Create a user. |
||
73 | * |
||
74 | * The User struct used to create the user will contain an ID which is used |
||
75 | * to reference the user. |
||
76 | * |
||
77 | * @param \eZ\Publish\SPI\Persistence\User $user |
||
78 | * |
||
79 | * @return \eZ\Publish\SPI\Persistence\User |
||
80 | */ |
||
81 | public function create(User $user) |
||
87 | |||
88 | /** |
||
89 | * Loads user with user ID. |
||
90 | * |
||
91 | * @param mixed $userId |
||
92 | * |
||
93 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
94 | * |
||
95 | * @return \eZ\Publish\SPI\Persistence\User |
||
96 | */ |
||
97 | View Code Duplication | public function load($userId) |
|
107 | |||
108 | /** |
||
109 | * Loads user with user login. |
||
110 | * |
||
111 | * @param string $login |
||
112 | * |
||
113 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
114 | * |
||
115 | * @return \eZ\Publish\SPI\Persistence\User |
||
116 | */ |
||
117 | public function loadByLogin($login) |
||
129 | |||
130 | /** |
||
131 | * Loads user(s) with user email. |
||
132 | * |
||
133 | * As earlier eZ Publish versions supported several users having same email (ini config), |
||
134 | * this function may return several users. |
||
135 | * |
||
136 | * @param string $email |
||
137 | * |
||
138 | * @return \eZ\Publish\SPI\Persistence\User[] |
||
139 | */ |
||
140 | public function loadByEmail($email) |
||
150 | |||
151 | /** |
||
152 | * Loads user with user hash. |
||
153 | * |
||
154 | * @param string $hash |
||
155 | * |
||
156 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If user is not found |
||
157 | * |
||
158 | * @return \eZ\Publish\SPI\Persistence\User |
||
159 | */ |
||
160 | View Code Duplication | public function loadUserByToken($hash) |
|
170 | |||
171 | /** |
||
172 | * Update the user information specified by the user struct. |
||
173 | * |
||
174 | * @param \eZ\Publish\SPI\Persistence\User $user |
||
175 | */ |
||
176 | public function update(User $user) |
||
180 | |||
181 | /** |
||
182 | * Update the user token information specified by the userToken struct. |
||
183 | * |
||
184 | * @param \eZ\Publish\SPI\Persistence\User\UserTokenUpdateStruct $userTokenUpdateStruct |
||
185 | */ |
||
186 | public function updateUserToken(UserTokenUpdateStruct $userTokenUpdateStruct) |
||
190 | |||
191 | /** |
||
192 | * Expires user account key with user hash. |
||
193 | * |
||
194 | * @param string $hash |
||
195 | */ |
||
196 | public function expireUserToken($hash) |
||
200 | |||
201 | /** |
||
202 | * Delete user with the given ID. |
||
203 | * |
||
204 | * @param mixed $userId |
||
205 | */ |
||
206 | public function delete($userId) |
||
210 | |||
211 | /** |
||
212 | * Create new role draft. |
||
213 | * |
||
214 | * Sets status to Role::STATUS_DRAFT on the new returned draft. |
||
215 | * |
||
216 | * @param \eZ\Publish\SPI\Persistence\User\RoleCreateStruct $createStruct |
||
217 | * |
||
218 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
219 | */ |
||
220 | public function createRole(RoleCreateStruct $createStruct) |
||
224 | |||
225 | /** |
||
226 | * Creates a draft of existing defined role. |
||
227 | * |
||
228 | * Sets status to Role::STATUS_DRAFT on the new returned draft. |
||
229 | * |
||
230 | * @param mixed $roleId |
||
231 | * |
||
232 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role with defined status is not found |
||
233 | * |
||
234 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
235 | */ |
||
236 | public function createRoleDraft($roleId) |
||
244 | |||
245 | /** |
||
246 | * Internal method for creating Role. |
||
247 | * |
||
248 | * Used by self::createRole() and self::createRoleDraft() |
||
249 | * |
||
250 | * @param \eZ\Publish\SPI\Persistence\User\RoleCreateStruct $createStruct |
||
251 | * @param mixed|null $roleId Used by self::createRoleDraft() to retain Role id in the draft |
||
252 | * |
||
253 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
254 | */ |
||
255 | protected function internalCreateRole(RoleCreateStruct $createStruct, $roleId = null) |
||
272 | |||
273 | /** |
||
274 | * Loads a specified role (draft) by $roleId and $status. |
||
275 | * |
||
276 | * @param mixed $roleId |
||
277 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
278 | * |
||
279 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role with given status does not exist |
||
280 | * |
||
281 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
282 | */ |
||
283 | View Code Duplication | public function loadRole($roleId, $status = Role::STATUS_DEFINED) |
|
298 | |||
299 | /** |
||
300 | * Loads a specified role (draft) by $identifier and $status. |
||
301 | * |
||
302 | * @param string $identifier |
||
303 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
304 | * |
||
305 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role is not found |
||
306 | * |
||
307 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
308 | */ |
||
309 | View Code Duplication | public function loadRoleByIdentifier($identifier, $status = Role::STATUS_DEFINED) |
|
324 | |||
325 | /** |
||
326 | * Loads a role draft by the original role ID. |
||
327 | * |
||
328 | * @param mixed $roleId ID of the role the draft was created from. |
||
329 | * |
||
330 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role is not found |
||
331 | * |
||
332 | * @return \eZ\Publish\SPI\Persistence\User\Role |
||
333 | */ |
||
334 | View Code Duplication | public function loadRoleDraftByRoleId($roleId) |
|
349 | |||
350 | /** |
||
351 | * Loads all roles. |
||
352 | * |
||
353 | * @return \eZ\Publish\SPI\Persistence\User\Role[] |
||
354 | */ |
||
355 | View Code Duplication | public function loadRoles() |
|
368 | |||
369 | /** |
||
370 | * Update role (draft). |
||
371 | * |
||
372 | * @param \eZ\Publish\SPI\Persistence\User\RoleUpdateStruct $role |
||
373 | */ |
||
374 | public function updateRole(RoleUpdateStruct $role) |
||
378 | |||
379 | /** |
||
380 | * Delete the specified role (draft). |
||
381 | * |
||
382 | * @param mixed $roleId |
||
383 | * @param int $status One of Role::STATUS_DEFINED|Role::STATUS_DRAFT |
||
384 | */ |
||
385 | public function deleteRole($roleId, $status = Role::STATUS_DEFINED) |
||
395 | |||
396 | /** |
||
397 | * Publish the specified role draft. |
||
398 | * |
||
399 | * @param mixed $roleDraftId |
||
400 | */ |
||
401 | public function publishRoleDraft($roleDraftId) |
||
428 | |||
429 | /** |
||
430 | * Adds a policy to a role draft. |
||
431 | * |
||
432 | * @param mixed $roleId |
||
433 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
434 | * |
||
435 | * @return \eZ\Publish\SPI\Persistence\User\Policy |
||
436 | */ |
||
437 | public function addPolicyByRoleDraft($roleId, Policy $policy) |
||
450 | |||
451 | /** |
||
452 | * Adds a policy to a role. |
||
453 | * |
||
454 | * @param mixed $roleId |
||
455 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
456 | * |
||
457 | * @return \eZ\Publish\SPI\Persistence\User\Policy |
||
458 | */ |
||
459 | public function addPolicy($roleId, Policy $policy) |
||
470 | |||
471 | /** |
||
472 | * Update a policy. |
||
473 | * |
||
474 | * Replaces limitations values with new values. |
||
475 | * |
||
476 | * @param \eZ\Publish\SPI\Persistence\User\Policy $policy |
||
477 | */ |
||
478 | public function updatePolicy(Policy $policy) |
||
486 | |||
487 | /** |
||
488 | * Removes a policy from a role. |
||
489 | * |
||
490 | * @param mixed $policyId |
||
491 | * @param mixed $roleId |
||
492 | */ |
||
493 | public function deletePolicy($policyId, $roleId) |
||
500 | |||
501 | /** |
||
502 | * Returns the user policies associated with the user (including inherited policies from user groups). |
||
503 | * |
||
504 | * @param mixed $userId |
||
505 | * |
||
506 | * @return \eZ\Publish\SPI\Persistence\User\Policy[] |
||
507 | */ |
||
508 | View Code Duplication | public function loadPoliciesByUserId($userId) |
|
520 | |||
521 | /** |
||
522 | * Assigns role to a user or user group with given limitations. |
||
523 | * |
||
524 | * The limitation array looks like: |
||
525 | * <code> |
||
526 | * array( |
||
527 | * 'Subtree' => array( |
||
528 | * '/1/2/', |
||
529 | * '/1/4/', |
||
530 | * ), |
||
531 | * 'Foo' => array( 'Bar' ), |
||
532 | * … |
||
533 | * ) |
||
534 | * </code> |
||
535 | * |
||
536 | * Where the keys are the limitation identifiers, and the respective values |
||
537 | * are an array of limitation values. The limitation parameter is optional. |
||
538 | * |
||
539 | * @param mixed $contentId The groupId or userId to assign the role to. |
||
540 | * @param mixed $roleId |
||
541 | * @param array $limitation |
||
542 | */ |
||
543 | public function assignRole($contentId, $roleId, array $limitation = null) |
||
548 | |||
549 | /** |
||
550 | * Un-assign a role. |
||
551 | * |
||
552 | * @param mixed $contentId The user or user group Id to un-assign the role from. |
||
553 | * @param mixed $roleId |
||
554 | */ |
||
555 | public function unassignRole($contentId, $roleId) |
||
559 | |||
560 | /** |
||
561 | * Un-assign a role by assignment ID. |
||
562 | * |
||
563 | * @param mixed $roleAssignmentId The assignment ID. |
||
564 | */ |
||
565 | public function removeRoleAssignment($roleAssignmentId) |
||
569 | |||
570 | /** |
||
571 | * Loads role assignment for specified assignment ID. |
||
572 | * |
||
573 | * @param mixed $roleAssignmentId |
||
574 | * |
||
575 | * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException If role assignment is not found |
||
576 | * |
||
577 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment |
||
578 | */ |
||
579 | public function loadRoleAssignment($roleAssignmentId) |
||
589 | |||
590 | /** |
||
591 | * Loads roles assignments Role. |
||
592 | * |
||
593 | * Role Assignments with same roleId and limitationIdentifier will be merged together into one. |
||
594 | * |
||
595 | * @param mixed $roleId |
||
596 | * |
||
597 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment[] |
||
598 | */ |
||
599 | View Code Duplication | public function loadRoleAssignmentsByRoleId($roleId) |
|
609 | |||
610 | /** |
||
611 | * Loads roles assignments to a user/group. |
||
612 | * |
||
613 | * Role Assignments with same roleId and limitationIdentifier will be merged together into one. |
||
614 | * |
||
615 | * @param mixed $groupId In legacy storage engine this is the content object id roles are assigned to in ezuser_role. |
||
616 | * By the nature of legacy this can currently also be used to get by $userId. |
||
617 | * @param bool $inherit If true also return inherited role assignments from user groups. |
||
618 | * |
||
619 | * @return \eZ\Publish\SPI\Persistence\User\RoleAssignment[] |
||
620 | */ |
||
621 | View Code Duplication | public function loadRoleAssignmentsByGroupId($groupId, $inherit = false) |
|
631 | } |
||
632 |
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.