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 Auth_Basic 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 Auth_Basic, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
24 | class Auth_Basic extends AbstractController |
||
25 | { |
||
26 | /** |
||
27 | * Info will contain data loaded about authenticated user. |
||
28 | * This property can be accessed through $this->get() and should not be changed after authentication. |
||
29 | * |
||
30 | * @var array|bool |
||
31 | */ |
||
32 | public $info = false; |
||
33 | |||
34 | /** |
||
35 | * This form is created when user is being asked about authentication. |
||
36 | * If you are willing to change the way form looks, create it prior to calling check(). |
||
37 | * Your form must have compatible field names: "username" and "password". |
||
38 | * |
||
39 | * @var Form |
||
40 | */ |
||
41 | public $form = null; |
||
42 | |||
43 | /** |
||
44 | * @var string|callable Which encryption to use. Few are built-in |
||
45 | */ |
||
46 | protected $password_encryption = null; |
||
47 | |||
48 | /** |
||
49 | * @var array Array of allowed page names |
||
50 | */ |
||
51 | protected $allowed_pages = array(); |
||
52 | |||
53 | /** |
||
54 | * @var string Login field name in model |
||
55 | */ |
||
56 | public $login_field = 'email'; |
||
57 | |||
58 | /** |
||
59 | * @var string Password field name in model |
||
60 | */ |
||
61 | public $password_field = 'password'; |
||
62 | |||
63 | /** |
||
64 | * @var int Encyption algorithm |
||
65 | */ |
||
66 | public $hash_algo = PASSWORD_DEFAULT; |
||
67 | |||
68 | /** |
||
69 | * @var array Encryption algorithm options |
||
70 | */ |
||
71 | public $hash_options = array(); |
||
72 | |||
73 | /** |
||
74 | * @var string Layout class |
||
75 | */ |
||
76 | public $login_layout_class = 'Layout_Centered'; |
||
77 | |||
78 | /** @var App_Frontend */ |
||
79 | public $app; |
||
80 | |||
81 | |||
82 | |||
83 | public function init() |
||
101 | |||
102 | /** |
||
103 | * Configure this Auth controller with a generic Model based on static |
||
104 | * collection of user/password combinations. Use this method if you |
||
105 | * only want one or few accounts to access the system. |
||
106 | * |
||
107 | * @param string|array $user Either string username or associative array with data |
||
108 | * @param string $pass Password if username is string |
||
109 | * |
||
110 | * @return $this |
||
111 | */ |
||
112 | public function allow($user, $pass = null) |
||
133 | /** |
||
134 | * Associate model with authentication class. Username / password |
||
135 | * check will be performed against the model in the following steps: |
||
136 | * Model will attempt to load record where login_field matches |
||
137 | * specified. Password is then loaded and verified using configured |
||
138 | * encryption method. |
||
139 | * |
||
140 | * @param string|object $model |
||
141 | * @param string $login_field |
||
142 | * @param string $password_field |
||
143 | * |
||
144 | * @return Model |
||
145 | */ |
||
146 | public function setModel($model, $login_field = 'email', $password_field = 'password') |
||
199 | /** |
||
200 | * Adds a hook to specified model which will encrypt password before save. |
||
201 | * This method will be applied on $this->model, so you should not call |
||
202 | * it manually. You can call it on a fresh model, however. |
||
203 | * |
||
204 | * @param Model $model |
||
205 | */ |
||
206 | public function addEncryptionHook($model) |
||
220 | |||
221 | /** |
||
222 | * Destroy object |
||
223 | */ |
||
224 | public function destroy() |
||
229 | |||
230 | /** |
||
231 | * Auth memorizes data about a logged-in user in session. You can either use this function to access |
||
232 | * that data or $auth->model (preferred) $auth->get('username') will always point to the login field |
||
233 | * value ofthe user regardless of how your field is named. |
||
234 | * |
||
235 | * @param string $property |
||
236 | * @param mixed $default |
||
237 | * |
||
238 | * @return mixed |
||
239 | */ |
||
240 | public function get($property = null, $default = null) |
||
251 | |||
252 | /** |
||
253 | * Return array of all authenticated session info |
||
254 | * |
||
255 | * @return array |
||
256 | */ |
||
257 | public function getAll() |
||
261 | |||
262 | /** |
||
263 | * Specify page or array of pages which will exclude authentication. Add your registration page here |
||
264 | * or page containing terms and conditions. |
||
265 | * |
||
266 | * @param string|array $page |
||
267 | * |
||
268 | * @return $this |
||
269 | */ |
||
270 | public function allowPage($page) |
||
283 | |||
284 | /** |
||
285 | * Return array of all allowed page names |
||
286 | * |
||
287 | * @return array |
||
288 | */ |
||
289 | public function getAllowedPages() |
||
293 | |||
294 | /** |
||
295 | * Verifies if the specified page is allowed to be accessed without |
||
296 | * authentication. |
||
297 | * |
||
298 | * @param string $page |
||
299 | * |
||
300 | * @return bool |
||
301 | */ |
||
302 | public function isPageAllowed($page) |
||
310 | |||
311 | /** |
||
312 | * Specifies how password will be encrypted when stored. It's recommended |
||
313 | * that you do not specify encryption method, in which case a built-in |
||
314 | * password_hash() will be used, which is defined by PHP. |
||
315 | * |
||
316 | * Some other values are "sha256/salt", "md5", "rot13". Note that if your |
||
317 | * application is already using 'md5' or 'sha1', you can remove the |
||
318 | * argument entirely and your user passwords will keep working and will |
||
319 | * automatically be "upgraded" to password_hash when used. |
||
320 | * |
||
321 | * If you are having trouble with authentication, use auth->debug() |
||
322 | * |
||
323 | * @param string|callable $method |
||
324 | * |
||
325 | * @return $this |
||
326 | */ |
||
327 | public function usePasswordEncryption($method = 'php') |
||
333 | |||
334 | /** |
||
335 | * Manually encrypt password |
||
336 | * |
||
337 | * @param string $password |
||
338 | * @param string $salt |
||
339 | * |
||
340 | * @return string|bool Returns false on failure, encrypted string otherwise |
||
341 | */ |
||
342 | public function encryptPassword($password, $salt = null) |
||
381 | |||
382 | /** |
||
383 | * Call this function to perform a check for logged in user. This will also display a login-form |
||
384 | * and will verify user's credential. If you want to handle log-in form on your own, use |
||
385 | * auth->isLoggedIn() to check and redirect user to a login page. |
||
386 | * |
||
387 | * check() returns true if user have just logged in and will return "null" for requests when user |
||
388 | * continues to use his session. Use that to perform some calculation on log-in |
||
389 | * |
||
390 | * @return bool |
||
391 | */ |
||
392 | public function check() |
||
428 | |||
429 | /** |
||
430 | * Add additional info to be stored in user session. |
||
431 | * |
||
432 | * @param string|array $key |
||
433 | * @param mixed $val |
||
434 | * |
||
435 | * @return $this |
||
436 | */ |
||
437 | public function addInfo($key, $val = null) |
||
452 | |||
453 | /** |
||
454 | * This function determines - if user is already logged in or not. It does it by |
||
455 | * looking at $this->info, which was loaded during init() from session. |
||
456 | * |
||
457 | * @return bool |
||
458 | */ |
||
459 | public function isLoggedIn() |
||
463 | |||
464 | /** |
||
465 | * This function verifies credibility of supplied authenication data. |
||
466 | * It will search based on user and verify the password. It's also |
||
467 | * possible that the function will re-hash user password with |
||
468 | * updated hash. |
||
469 | * |
||
470 | * if default authentication method is used, the function will |
||
471 | * automatically determine hash used for password generation and will |
||
472 | * upgrade to a new php5.5-compatible syntax. |
||
473 | * |
||
474 | * This function return false OR the id of the record matching user. |
||
475 | * |
||
476 | * @param string $user |
||
477 | * @param string $password |
||
478 | * |
||
479 | * @return mixed |
||
480 | */ |
||
481 | public function verifyCredentials($user, $password) |
||
603 | |||
604 | /** |
||
605 | * Memorize current URL. Called when the first unsuccessful check is executed. |
||
606 | */ |
||
607 | public function memorizeURL() |
||
616 | |||
617 | /** |
||
618 | * Return originalally requested URL. |
||
619 | * |
||
620 | * @return string |
||
621 | */ |
||
622 | public function getURL() |
||
637 | |||
638 | /** |
||
639 | * Rederect to page user tried to access before authentication was requested. |
||
640 | */ |
||
641 | public function loginRedirect() |
||
646 | |||
647 | /** |
||
648 | * This function is always executed after successfull login through a normal means (login form or plugin). |
||
649 | * |
||
650 | * It will create cache model data. |
||
651 | * |
||
652 | * @param string $user |
||
653 | * @param string $pass |
||
654 | */ |
||
655 | public function loggedIn($user = null, $pass = null) |
||
661 | |||
662 | /** |
||
663 | * Store model in session data so that it can be retrieved faster. |
||
664 | */ |
||
665 | public function memorizeModel() |
||
687 | |||
688 | /** |
||
689 | * Manually Log in as specified users. Will not perform password check or redirect. |
||
690 | * |
||
691 | * @param mixed $id |
||
692 | * |
||
693 | * @return $this |
||
694 | */ |
||
695 | public function loginByID($id) |
||
702 | |||
703 | /** |
||
704 | * Manually Log in with specified condition. |
||
705 | * |
||
706 | * @param string $field |
||
707 | * @param mixed $value |
||
708 | * |
||
709 | * @return $this |
||
710 | */ |
||
711 | public function loginBy($field, $value) |
||
718 | |||
719 | /** |
||
720 | * Manually Log in as specified users by using login name. |
||
721 | * |
||
722 | * @param string $user |
||
723 | * |
||
724 | * @return $this |
||
725 | */ |
||
726 | public function login($user) |
||
751 | |||
752 | /** |
||
753 | * Manually log out user. |
||
754 | * |
||
755 | * @return $this |
||
756 | */ |
||
757 | public function logout() |
||
776 | |||
777 | /** |
||
778 | * Creates log-in form. |
||
779 | * Override if you want to use your own form. If you need to change template used by a log-in form, |
||
780 | * add template/default/page/login.html. |
||
781 | * |
||
782 | * @param Page $page |
||
783 | * |
||
784 | * @return Form |
||
785 | */ |
||
786 | public function createForm($page) |
||
807 | |||
808 | /** |
||
809 | * Do not override this function. |
||
810 | * |
||
811 | * @return Page |
||
812 | */ |
||
813 | public function showLoginForm() |
||
849 | |||
850 | /** |
||
851 | * Do not override this function. |
||
852 | */ |
||
853 | public function processLogin() |
||
870 | } |
||
871 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.