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 XoopsUser 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 XoopsUser, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
27 | class XoopsUser extends XoopsObject |
||
28 | { |
||
29 | /** |
||
30 | * Array of groups that user belongs to |
||
31 | * @var array |
||
32 | * @access private |
||
33 | */ |
||
34 | public $_groups = array(); |
||
35 | /** |
||
36 | * @var bool is the user admin? |
||
37 | * @access private |
||
38 | */ |
||
39 | public $_isAdmin; |
||
40 | /** |
||
41 | * @var string user's rank |
||
42 | * @access private |
||
43 | */ |
||
44 | public $_rank; |
||
45 | /** |
||
46 | * @var bool is the user online? |
||
47 | * @access private |
||
48 | */ |
||
49 | public $_isOnline; |
||
50 | |||
51 | /** |
||
52 | * constructor |
||
53 | * @param array|null $id ID of the user to be loaded from the database. |
||
54 | */ |
||
55 | public function __construct($id = null) |
||
102 | |||
103 | /** |
||
104 | * check if the user is a guest user |
||
105 | * |
||
106 | * @return bool returns false |
||
107 | * |
||
108 | */ |
||
109 | public function isGuest() |
||
110 | { |
||
111 | return false; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Updated by Catzwolf 11 Jan 2004 |
||
116 | * find the username for a given ID |
||
117 | * |
||
118 | * @param int $userid ID of the user to find |
||
119 | * @param int $usereal switch for usename or realname |
||
120 | * @return string name of the user. name for 'anonymous' if not found. |
||
121 | */ |
||
122 | public static function getUnameFromId($userid, $usereal = 0) |
||
146 | |||
147 | /** |
||
148 | * increase the number of posts for the user |
||
149 | * |
||
150 | * @deprecated |
||
151 | */ |
||
152 | public function incrementPost() |
||
153 | { |
||
154 | $member_handler = xoops_getHandler('member'); |
||
155 | |||
156 | return $member_handler->updateUserByField($this, 'posts', $this->getVar('posts') + 1); |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * set the groups for the user |
||
161 | * |
||
162 | * @param array $groupsArr Array of groups that user belongs to |
||
163 | */ |
||
164 | public function setGroups($groupsArr) |
||
165 | { |
||
166 | if (is_array($groupsArr)) { |
||
167 | $this->_groups =& $groupsArr; |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * get the groups that the user belongs to |
||
173 | * |
||
174 | * @return array array of groups |
||
175 | */ |
||
176 | public function &getGroups() |
||
177 | { |
||
178 | if (empty($this->_groups)) { |
||
179 | $member_handler = xoops_getHandler('member'); |
||
180 | $this->_groups = $member_handler->getGroupsByUser($this->getVar('uid')); |
||
181 | } |
||
182 | |||
183 | return $this->_groups; |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * alias for {@link getGroups()} |
||
188 | * @see getGroups() |
||
189 | * @return array array of groups |
||
190 | * @deprecated |
||
191 | */ |
||
192 | public function &groups() |
||
193 | { |
||
194 | $groups =& $this->getGroups(); |
||
195 | |||
196 | return $groups; |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Is the user admin ? |
||
201 | * |
||
202 | * This method will return true if this user has admin rights for the specified module.<br /> |
||
203 | * - If you don't specify any module ID, the current module will be checked.<br /> |
||
204 | * - If you set the module_id to -1, it will return true if the user has admin rights for at least one module |
||
205 | * |
||
206 | * @param int $module_id check if user is admin of this module |
||
207 | * @return bool is the user admin of that module? |
||
208 | */ |
||
209 | public function isAdmin($module_id = null) |
||
210 | { |
||
211 | if (null === $module_id) { |
||
212 | $module_id = (isset($GLOBALS['xoopsModule']) && is_object($GLOBALS['xoopsModule'])) ? $GLOBALS['xoopsModule']->getVar('mid', 'n') : 1; |
||
213 | } elseif ((int)$module_id < 1) { |
||
214 | $module_id = 0; |
||
215 | } |
||
216 | $moduleperm_handler = xoops_getHandler('groupperm'); |
||
217 | |||
218 | return $moduleperm_handler->checkRight('module_admin', $module_id, $this->getGroups()); |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * get the user's rank |
||
223 | * @return array array of rank ID and title |
||
224 | */ |
||
225 | public function rank() |
||
226 | { |
||
227 | if (!isset($this->_rank)) { |
||
228 | $this->_rank = xoops_getrank($this->getVar('rank'), $this->getVar('posts')); |
||
229 | } |
||
230 | |||
231 | return $this->_rank; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * is the user activated? |
||
236 | * @return bool |
||
237 | */ |
||
238 | public function isActive() |
||
242 | |||
243 | /** |
||
244 | * is the user currently logged in? |
||
245 | * @return bool |
||
246 | */ |
||
247 | public function isOnline() |
||
248 | { |
||
256 | |||
257 | /** |
||
258 | * get the users UID |
||
259 | * @param string $format |
||
260 | * @return int |
||
261 | */ |
||
262 | public function uid($format = '') |
||
266 | |||
267 | /** |
||
268 | * get the users UID |
||
269 | * @param string $format |
||
270 | * @return int |
||
271 | */ |
||
272 | public function id($format = 'N') |
||
276 | |||
277 | /** |
||
278 | * get the users name |
||
279 | * @param string $format format for the output, see {@link XoopsObject::getVar($format = '')} |
||
280 | * @return string |
||
281 | */ |
||
282 | public function name($format = 'S') |
||
286 | |||
287 | /** |
||
288 | * get the user's uname |
||
289 | * @param string $format format for the output, see {@link XoopsObject::getVar($format = '')} |
||
290 | * @return string |
||
291 | */ |
||
292 | public function uname($format = 'S') |
||
296 | |||
297 | /** |
||
298 | * get the user's email |
||
299 | * |
||
300 | * @param string $format format for the output, see {@link XoopsObject::getVar($format = '')} |
||
301 | * @return string |
||
302 | */ |
||
303 | public function email($format = 'S') |
||
307 | |||
308 | /** |
||
309 | * @param string $format |
||
310 | * |
||
311 | * @return mixed |
||
312 | */ |
||
313 | public function url($format = 'S') |
||
317 | |||
318 | /** |
||
319 | * @param string $format |
||
320 | * |
||
321 | * @return mixed |
||
322 | */ |
||
323 | public function user_avatar($format = 'S') |
||
327 | |||
328 | /** |
||
329 | * @param string $format |
||
330 | * |
||
331 | * @return mixed |
||
332 | */ |
||
333 | public function user_regdate($format = '') |
||
337 | |||
338 | /** |
||
339 | * @param string $format |
||
340 | * |
||
341 | * @return mixed |
||
342 | */ |
||
343 | public function user_icq($format = 'S') |
||
347 | |||
348 | /** |
||
349 | * @param string $format |
||
350 | * |
||
351 | * @return mixed |
||
352 | */ |
||
353 | public function user_from($format = 'S') |
||
357 | |||
358 | /** |
||
359 | * @param string $format |
||
360 | * |
||
361 | * @return mixed |
||
362 | */ |
||
363 | public function user_sig($format = 'S') |
||
367 | |||
368 | /** |
||
369 | * @param string $format |
||
370 | * |
||
371 | * @return mixed |
||
372 | */ |
||
373 | public function user_viewemail($format = '') |
||
377 | |||
378 | /** |
||
379 | * @param string $format |
||
380 | * |
||
381 | * @return mixed |
||
382 | */ |
||
383 | public function actkey($format = '') |
||
387 | |||
388 | /** |
||
389 | * @param string $format |
||
390 | * |
||
391 | * @return mixed |
||
392 | */ |
||
393 | public function user_aim($format = 'S') |
||
397 | |||
398 | /** |
||
399 | * @param string $format |
||
400 | * |
||
401 | * @return mixed |
||
402 | */ |
||
403 | public function user_yim($format = 'S') |
||
407 | |||
408 | /** |
||
409 | * @param string $format |
||
410 | * |
||
411 | * @return mixed |
||
412 | */ |
||
413 | public function user_msnm($format = 'S') |
||
417 | |||
418 | /** |
||
419 | * @param string $format |
||
420 | * |
||
421 | * @return mixed |
||
422 | */ |
||
423 | public function pass($format = '') |
||
427 | |||
428 | /** |
||
429 | * @param string $format |
||
430 | * |
||
431 | * @return mixed |
||
432 | */ |
||
433 | public function posts($format = '') |
||
437 | |||
438 | /** |
||
439 | * @param string $format |
||
440 | * |
||
441 | * @return mixed |
||
442 | */ |
||
443 | public function attachsig($format = '') |
||
447 | |||
448 | /** |
||
449 | * @param string $format |
||
450 | * |
||
451 | * @return mixed |
||
452 | */ |
||
453 | public function level($format = '') |
||
457 | |||
458 | /** |
||
459 | * @param string $format |
||
460 | * |
||
461 | * @return mixed |
||
462 | */ |
||
463 | public function theme($format = '') |
||
467 | |||
468 | /** |
||
469 | * @param string $format |
||
470 | * |
||
471 | * @return mixed |
||
472 | */ |
||
473 | public function timezone($format = '') |
||
477 | |||
478 | /** |
||
479 | * @param string $format |
||
480 | * |
||
481 | * @return mixed |
||
482 | */ |
||
483 | public function umode($format = '') |
||
487 | |||
488 | /** |
||
489 | * @param string $format |
||
490 | * |
||
491 | * @return mixed |
||
492 | */ |
||
493 | public function uorder($format = '') |
||
497 | |||
498 | // RMV-NOTIFY |
||
499 | /** |
||
500 | * @param string $format |
||
501 | * |
||
502 | * @return mixed |
||
503 | */ |
||
504 | public function notify_method($format = '') |
||
508 | |||
509 | /** |
||
510 | * @param string $format |
||
511 | * |
||
512 | * @return mixed |
||
513 | */ |
||
514 | public function notify_mode($format = '') |
||
518 | |||
519 | /** |
||
520 | * @param string $format |
||
521 | * |
||
522 | * @return mixed |
||
523 | */ |
||
524 | public function user_occ($format = 'S') |
||
528 | |||
529 | /** |
||
530 | * @param string $format |
||
531 | * |
||
532 | * @return mixed |
||
533 | */ |
||
534 | public function bio($format = 'S') |
||
538 | |||
539 | /** |
||
540 | * @param string $format |
||
541 | * |
||
542 | * @return mixed |
||
543 | */ |
||
544 | public function user_intrest($format = 'S') |
||
548 | /**#@-*/ |
||
549 | |||
550 | /**#@+ |
||
551 | * @deprecated |
||
552 | */ |
||
553 | public function getProfile() |
||
559 | /**#@-*/ |
||
560 | } |
||
561 | |||
630 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.