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 ElggGroup 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 ElggGroup, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class ElggGroup extends \ElggEntity |
||
13 | implements Friendable { |
||
14 | |||
15 | const CONTENT_ACCESS_MODE_UNRESTRICTED = 'unrestricted'; |
||
16 | const CONTENT_ACCESS_MODE_MEMBERS_ONLY = 'members_only'; |
||
17 | |||
18 | /** |
||
19 | * Sets the type to group. |
||
20 | * |
||
21 | * @return void |
||
22 | */ |
||
23 | 1 | View Code Duplication | protected function initializeAttributes() { |
30 | |||
31 | /** |
||
32 | * Get default values for attributes stored in a separate table |
||
33 | * |
||
34 | * @return array |
||
35 | * @access private |
||
36 | * |
||
37 | * @see \Elgg\Database\EntityTable::getEntities |
||
38 | */ |
||
39 | 1 | final public static function getExternalAttributes() { |
|
45 | |||
46 | /** |
||
47 | * Construct a new group entity |
||
48 | * |
||
49 | * Plugin developers should only use the constructor to create a new entity. |
||
50 | * To retrieve entities, use get_entity() and the elgg_get_entities* functions. |
||
51 | * |
||
52 | * @param \stdClass $row Database row result. Default is null to create a new group. |
||
53 | * |
||
54 | * @throws IOException|InvalidParameterException if there was a problem creating the group. |
||
55 | */ |
||
56 | 1 | View Code Duplication | public function __construct($row = null) { |
87 | |||
88 | /** |
||
89 | * {@inheritdoc} |
||
90 | */ |
||
91 | public function getDisplayName() { |
||
94 | |||
95 | /** |
||
96 | * {@inheritdoc} |
||
97 | */ |
||
98 | public function setDisplayName($displayName) { |
||
101 | |||
102 | /** |
||
103 | * Add an \ElggObject to this group. |
||
104 | * |
||
105 | * @param \ElggObject $object The object. |
||
106 | * |
||
107 | * @return bool |
||
108 | */ |
||
109 | 1 | public function addObjectToGroup(\ElggObject $object) { |
|
113 | |||
114 | /** |
||
115 | * Remove an object from this containing group and sets the container to be |
||
116 | * object's owner |
||
117 | * |
||
118 | * @param \ElggObject $object The object. |
||
119 | * |
||
120 | * @return bool |
||
121 | */ |
||
122 | public function removeObjectFromGroup($object) { |
||
134 | |||
135 | /** |
||
136 | * Wrapper around \ElggEntity::__get() |
||
137 | * |
||
138 | * @see \ElggEntity::__get() |
||
139 | * |
||
140 | * @param string $name Name |
||
141 | * @return mixed |
||
142 | * @todo deprecate appending group to username. Was a hack used for creating |
||
143 | * URLs for group content. We stopped using the hack in 1.8. |
||
144 | */ |
||
145 | public function __get($name) { |
||
151 | |||
152 | /** |
||
153 | * Wrapper around \ElggEntity::get() |
||
154 | * |
||
155 | * @param string $name Name |
||
156 | * @return mixed |
||
157 | * @deprecated 1.9 |
||
158 | */ |
||
159 | public function get($name) { |
||
163 | |||
164 | /** |
||
165 | * Start friendable compatibility block: |
||
166 | * |
||
167 | * public function addFriend($friend_guid); |
||
168 | public function removeFriend($friend_guid); |
||
169 | public function isFriend(); |
||
170 | public function isFriendsWith($user_guid); |
||
171 | public function isFriendOf($user_guid); |
||
172 | public function getFriends($subtype = "", $limit = 10, $offset = 0); |
||
173 | public function getFriendsOf($subtype = "", $limit = 10, $offset = 0); |
||
174 | public function getObjects($subtype="", $limit = 10, $offset = 0); |
||
175 | public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0); |
||
176 | public function countObjects($subtype = ""); |
||
177 | */ |
||
178 | |||
179 | /** |
||
180 | * For compatibility with Friendable. |
||
181 | * |
||
182 | * Join a group when you friend \ElggGroup. |
||
183 | * |
||
184 | * @param int $friend_guid The GUID of the user joining the group. |
||
185 | * |
||
186 | * @return bool |
||
187 | * @deprecated 1.9 Use \ElggGroup::join() |
||
188 | */ |
||
189 | public function addFriend($friend_guid) { |
||
194 | |||
195 | /** |
||
196 | * For compatibility with Friendable |
||
197 | * |
||
198 | * Leave group when you unfriend \ElggGroup. |
||
199 | * |
||
200 | * @param int $friend_guid The GUID of the user leaving. |
||
201 | * |
||
202 | * @return bool |
||
203 | * @deprecated 1.9 Use \ElggGroup::leave() |
||
204 | */ |
||
205 | public function removeFriend($friend_guid) { |
||
210 | |||
211 | /** |
||
212 | * For compatibility with Friendable |
||
213 | * |
||
214 | * Friending a group adds you as a member |
||
215 | * |
||
216 | * @return bool |
||
217 | * @deprecated 1.9 Use \ElggGroup::isMember() |
||
218 | */ |
||
219 | public function isFriend() { |
||
223 | |||
224 | /** |
||
225 | * For compatibility with Friendable |
||
226 | * |
||
227 | * @param int $user_guid The GUID of a user to check. |
||
228 | * |
||
229 | * @return bool |
||
230 | * @deprecated 1.9 Use \ElggGroup::isMember() |
||
231 | */ |
||
232 | public function isFriendsWith($user_guid) { |
||
237 | |||
238 | /** |
||
239 | * For compatibility with Friendable |
||
240 | * |
||
241 | * @param int $user_guid The GUID of a user to check. |
||
242 | * |
||
243 | * @return bool |
||
244 | * @deprecated 1.9 Use \ElggGroup::isMember() |
||
245 | */ |
||
246 | public function isFriendOf($user_guid) { |
||
251 | |||
252 | /** |
||
253 | * For compatibility with Friendable |
||
254 | * |
||
255 | * @param string $subtype The GUID of a user to check. |
||
256 | * @param int $limit Limit |
||
257 | * @param int $offset Offset |
||
258 | * |
||
259 | * @return bool |
||
260 | * @deprecated 1.9 Use \ElggGroup::getMembers() |
||
261 | */ |
||
262 | public function getFriends($subtype = "", $limit = 10, $offset = 0) { |
||
266 | |||
267 | /** |
||
268 | * For compatibility with Friendable |
||
269 | * |
||
270 | * @param string $subtype The GUID of a user to check. |
||
271 | * @param int $limit Limit |
||
272 | * @param int $offset Offset |
||
273 | * |
||
274 | * @return bool |
||
275 | * @deprecated 1.9 Use \ElggGroup::getMembers() |
||
276 | */ |
||
277 | public function getFriendsOf($subtype = "", $limit = 10, $offset = 0) { |
||
281 | |||
282 | /** |
||
283 | * Get objects contained in this group. |
||
284 | * |
||
285 | * @param string $subtype Entity subtype |
||
286 | * @param int $limit Limit |
||
287 | * @param int $offset Offset |
||
288 | * |
||
289 | * @return array|false |
||
290 | * @deprecated 1.9 Use elgg_get_entities() |
||
291 | */ |
||
292 | public function getObjects($subtype = "", $limit = 10, $offset = 0) { |
||
296 | |||
297 | /** |
||
298 | * For compatibility with Friendable |
||
299 | * |
||
300 | * @param string $subtype Entity subtype |
||
301 | * @param int $limit Limit |
||
302 | * @param int $offset Offset |
||
303 | * |
||
304 | * @return array|false |
||
305 | * @deprecated 1.9 Use elgg_get_entities() |
||
306 | */ |
||
307 | public function getFriendsObjects($subtype = "", $limit = 10, $offset = 0) { |
||
311 | |||
312 | /** |
||
313 | * For compatibility with Friendable |
||
314 | * |
||
315 | * @param string $subtype Subtype of entities |
||
316 | * |
||
317 | * @return array|false |
||
318 | * @deprecated 1.9 Use elgg_get_entities() |
||
319 | */ |
||
320 | public function countObjects($subtype = "") { |
||
324 | |||
325 | /** |
||
326 | * End friendable compatibility block |
||
327 | */ |
||
328 | |||
329 | /** |
||
330 | * Get an array of group members. |
||
331 | * |
||
332 | * @param array $options Options array. See elgg_get_entities_from_relationships |
||
333 | * for a complete list. Common ones are 'limit', 'offset', |
||
334 | * and 'count'. Options set automatically are 'relationship', |
||
335 | * 'relationship_guid', 'inverse_relationship', and 'type'. This argument |
||
336 | * used to set the limit (deprecated usage) |
||
337 | * @param int $offset Offset (deprecated) |
||
338 | * @param bool $count Count (deprecated) |
||
339 | * |
||
340 | * @return array |
||
341 | */ |
||
342 | public function getMembers($options = array(), $offset = 0, $count = false) { |
||
363 | |||
364 | /** |
||
365 | * Returns whether the current group has open membership or not. |
||
366 | * |
||
367 | * @return bool |
||
368 | */ |
||
369 | public function isPublicMembership() { |
||
372 | |||
373 | /** |
||
374 | * Return the content access mode used by group_gatekeeper() |
||
375 | * |
||
376 | * @return string One of CONTENT_ACCESS_MODE_* constants |
||
377 | * @access private |
||
378 | * @since 1.9.0 |
||
379 | */ |
||
380 | public function getContentAccessMode() { |
||
399 | |||
400 | /** |
||
401 | * Set the content access mode used by group_gatekeeper() |
||
402 | * |
||
403 | * @param string $mode One of CONTENT_ACCESS_MODE_* constants |
||
404 | * @return void |
||
405 | * @access private |
||
406 | * @since 1.9.0 |
||
407 | */ |
||
408 | public function setContentAccessMode($mode) { |
||
416 | |||
417 | /** |
||
418 | * Is the given user a member of this group? |
||
419 | * |
||
420 | * @param \ElggUser $user The user. Default is logged in user. |
||
421 | * |
||
422 | * @return bool |
||
423 | */ |
||
424 | public function isMember(\ElggUser $user = null) { |
||
440 | |||
441 | /** |
||
442 | * Join a user to this group. |
||
443 | * |
||
444 | * @param \ElggUser $user User joining the group. |
||
445 | * |
||
446 | * @return bool Whether joining was successful. |
||
447 | */ |
||
448 | public function join(\ElggUser $user) { |
||
458 | |||
459 | /** |
||
460 | * Remove a user from the group. |
||
461 | * |
||
462 | * @param \ElggUser $user User to remove from the group. |
||
463 | * |
||
464 | * @return bool Whether the user was removed from the group. |
||
465 | */ |
||
466 | public function leave(\ElggUser $user) { |
||
473 | |||
474 | /** |
||
475 | * Load the \ElggGroup data from the database |
||
476 | * |
||
477 | * @param mixed $guid GUID of an \ElggGroup entity or database row from entity table |
||
478 | * |
||
479 | * @return bool |
||
480 | */ |
||
481 | View Code Duplication | protected function load($guid) { |
|
498 | |||
499 | /** |
||
500 | * {@inheritdoc} |
||
501 | */ |
||
502 | protected function update() { |
||
518 | |||
519 | /** |
||
520 | * {@inheritdoc} |
||
521 | */ |
||
522 | View Code Duplication | protected function create() { |
|
546 | |||
547 | /** |
||
548 | * {@inheritdoc} |
||
549 | */ |
||
550 | View Code Duplication | protected function prepareObject($object) { |
|
557 | |||
558 | |||
559 | // EXPORTABLE INTERFACE //////////////////////////////////////////////////////////// |
||
560 | |||
561 | /** |
||
562 | * Return an array of fields which can be exported. |
||
563 | * |
||
564 | * @return array |
||
565 | * @deprecated 1.9 Use toObject() |
||
566 | */ |
||
567 | public function getExportableValues() { |
||
573 | |||
574 | /** |
||
575 | * Can a user comment on this group? |
||
576 | * |
||
577 | * @see \ElggEntity::canComment() |
||
578 | * |
||
579 | * @param int $user_guid User guid (default is logged in user) |
||
580 | * @return bool |
||
581 | * @since 1.8.0 |
||
582 | */ |
||
583 | public function canComment($user_guid = 0) { |
||
590 | } |
||
591 |
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.