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 EE_Payment_Method_Manager 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 EE_Payment_Method_Manager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | class EE_Payment_Method_Manager implements ResettableInterface |
||
22 | { |
||
23 | |||
24 | /** |
||
25 | * prefix added to all payment method capabilities names |
||
26 | */ |
||
27 | const CAPABILITIES_PREFIX= 'ee_payment_method_'; |
||
28 | |||
29 | /** |
||
30 | * @var EE_Payment_Method_Manager $_instance |
||
31 | */ |
||
32 | private static $_instance; |
||
33 | |||
34 | /** |
||
35 | * @var boolean |
||
36 | */ |
||
37 | protected $payment_method_caps_initialized = false; |
||
38 | |||
39 | /** |
||
40 | * @var array keys are class names without 'EE_PMT_', values are their filepaths |
||
41 | */ |
||
42 | protected $_payment_method_types = array(); |
||
43 | |||
44 | /** |
||
45 | * @var EE_PMT_Base[] |
||
46 | */ |
||
47 | protected $payment_method_objects = array(); |
||
48 | |||
49 | |||
50 | |||
51 | /** |
||
52 | * EE_Payment_Method_Manager constructor. |
||
53 | * |
||
54 | * @throws EE_Error |
||
55 | * @throws DomainException |
||
56 | */ |
||
57 | public function __construct() |
||
71 | |||
72 | |||
73 | |||
74 | /** |
||
75 | * @singleton method used to instantiate class object |
||
76 | * @return EE_Payment_Method_Manager instance |
||
77 | * @throws DomainException |
||
78 | * @throws EE_Error |
||
79 | */ |
||
80 | public static function instance() |
||
89 | |||
90 | |||
91 | |||
92 | /** |
||
93 | * Resets the instance and returns a new one |
||
94 | * |
||
95 | * @return EE_Payment_Method_Manager |
||
96 | * @throws DomainException |
||
97 | * @throws EE_Error |
||
98 | */ |
||
99 | public static function reset() |
||
104 | |||
105 | |||
106 | |||
107 | /** |
||
108 | * If necessary, re-register payment methods |
||
109 | * |
||
110 | * @param boolean $force_recheck whether to recheck for payment method types, |
||
111 | * or just re-use the PMTs we found last time we checked during this request (if |
||
112 | * we have not yet checked during this request, then we need to check anyways) |
||
113 | */ |
||
114 | public function maybe_register_payment_methods($force_recheck = false) |
||
120 | |||
121 | |||
122 | |||
123 | /** |
||
124 | * register_payment_methods |
||
125 | * |
||
126 | * @return array |
||
127 | */ |
||
128 | protected function _register_payment_methods() |
||
152 | |||
153 | |||
154 | |||
155 | /** |
||
156 | * register_payment_method- makes core aware of this payment method |
||
157 | * |
||
158 | * @param string $payment_method_path - full path up to and including payment method folder |
||
159 | * @return boolean |
||
160 | */ |
||
161 | public function register_payment_method($payment_method_path = '') |
||
199 | |||
200 | |||
201 | |||
202 | /** |
||
203 | * Checks if a payment method has been registered, and if so includes it |
||
204 | * |
||
205 | * @param string $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_') |
||
206 | * @param boolean $force_recheck whether to force re-checking for new payment method types |
||
207 | * @return boolean |
||
208 | */ |
||
209 | public function payment_method_type_exists($payment_method_name, $force_recheck = false) |
||
224 | |||
225 | |||
226 | |||
227 | /** |
||
228 | * Returns all the class names of the various payment method types |
||
229 | * |
||
230 | * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names' |
||
231 | * (what you'd find in wp_esp_payment_method.PMD_type) |
||
232 | * @param boolean $force_recheck whether to force re-checking for new payment method types |
||
233 | * @return array |
||
234 | */ |
||
235 | public function payment_method_type_names($with_prefixes = false, $force_recheck = false) |
||
248 | |||
249 | |||
250 | |||
251 | /** |
||
252 | * Gets an object of each payment method type, none of which are bound to a |
||
253 | * payment method instance |
||
254 | * |
||
255 | * @param boolean $force_recheck whether to force re-checking for new payment method types |
||
256 | * @return EE_PMT_Base[] |
||
257 | */ |
||
258 | public function payment_method_types($force_recheck = false) |
||
270 | |||
271 | |||
272 | |||
273 | /** |
||
274 | * Changes the payment method's class name into the payment method type's name |
||
275 | * (as used on the payment method's table's PMD_type field) |
||
276 | * |
||
277 | * @param string $classname |
||
278 | * @return string |
||
279 | */ |
||
280 | public function payment_method_type_sans_class_prefix($classname) |
||
284 | |||
285 | |||
286 | |||
287 | /** |
||
288 | * Does the opposite of payment-method_type_sans_prefix |
||
289 | * |
||
290 | * @param string $type |
||
291 | * @return string |
||
292 | */ |
||
293 | public function payment_method_class_from_type($type) |
||
297 | |||
298 | |||
299 | |||
300 | /** |
||
301 | * Activates a payment method of the given type. |
||
302 | * |
||
303 | * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice' |
||
304 | * @return EE_Payment_Method |
||
305 | * @throws InvalidDataTypeException |
||
306 | * @throws EE_Error |
||
307 | */ |
||
308 | public function activate_a_payment_method_of_type($payment_method_type) |
||
362 | |||
363 | |||
364 | |||
365 | /** |
||
366 | * Creates a payment method of the specified type. Does not save it. |
||
367 | * |
||
368 | * @global WP_User $current_user |
||
369 | * @param EE_PMT_Base $pm_type_obj |
||
370 | * @return EE_Payment_Method |
||
371 | * @throws EE_Error |
||
372 | */ |
||
373 | public function create_payment_method_of_type($pm_type_obj) |
||
390 | |||
391 | |||
392 | |||
393 | /** |
||
394 | * Sets the initial payment method properties (including extra meta) |
||
395 | * |
||
396 | * @param EE_Payment_Method $payment_method |
||
397 | * @return EE_Payment_Method |
||
398 | * @throws EE_Error |
||
399 | */ |
||
400 | public function initialize_payment_method($payment_method) |
||
420 | |||
421 | |||
422 | |||
423 | /** |
||
424 | * Makes sure the payment method is related to the specified payment method |
||
425 | * |
||
426 | * @deprecated in 4.9.40 because the currency payment method table is being deprecated |
||
427 | * @param EE_Payment_Method $payment_method |
||
428 | * @return EE_Payment_Method |
||
429 | * @throws EE_Error |
||
430 | */ |
||
431 | public function set_usable_currencies_on_payment_method($payment_method) |
||
443 | |||
444 | |||
445 | |||
446 | /** |
||
447 | * Deactivates a payment method of the given payment method slug. |
||
448 | * |
||
449 | * @param string $payment_method_slug The slug for the payment method to deactivate. |
||
450 | * @return int count of rows updated. |
||
451 | * @throws EE_Error |
||
452 | */ |
||
453 | public function deactivate_payment_method($payment_method_slug) |
||
473 | |||
474 | |||
475 | |||
476 | /** |
||
477 | * initializes payment method access caps via EE_Capabilities::init_role_caps() |
||
478 | * upon EE_Payment_Method_Manager construction |
||
479 | * |
||
480 | * @throws EE_Error |
||
481 | * @throws DomainException |
||
482 | */ |
||
483 | protected function initializePaymentMethodCaps() |
||
494 | |||
495 | |||
496 | |||
497 | /** |
||
498 | * array of dynamic payment method access caps. |
||
499 | * at the time of writing, october 20 2014, these are the caps added: |
||
500 | * ee_payment_method_admin_only |
||
501 | * ee_payment_method_aim |
||
502 | * ee_payment_method_bank |
||
503 | * ee_payment_method_check |
||
504 | * ee_payment_method_invoice |
||
505 | * ee_payment_method_mijireh |
||
506 | * ee_payment_method_paypal_pro |
||
507 | * ee_payment_method_paypal_standard |
||
508 | * Any other payment methods added to core or via addons will also get |
||
509 | * their related capability automatically added too, so long as they are |
||
510 | * registered properly using EE_Register_Payment_Method::register() |
||
511 | * |
||
512 | * @return array |
||
513 | * @throws DomainException |
||
514 | */ |
||
515 | protected function getPaymentMethodCaps() |
||
523 | |||
524 | |||
525 | |||
526 | /** |
||
527 | * @param string $payment_method_name |
||
528 | * @param array $payment_method_caps |
||
529 | * @param string $role |
||
530 | * @return array |
||
531 | * @throws DomainException |
||
532 | */ |
||
533 | public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator') |
||
561 | |||
562 | |||
563 | |||
564 | /** |
||
565 | * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter |
||
566 | * to add dynamic payment method access caps when capabilities are reset |
||
567 | * (or if that filter is called and PM caps are not already set) |
||
568 | * |
||
569 | * @param array $caps capabilities being filtered |
||
570 | * @param bool $reset |
||
571 | * @return array |
||
572 | * @throws DomainException |
||
573 | */ |
||
574 | public function addPaymentMethodCapsDuringReset(array $caps, $reset = false) |
||
582 | |||
583 | |||
584 | |||
585 | /** |
||
586 | * @deprecated 4.9.42 |
||
587 | * @param $caps |
||
588 | * @return mixed |
||
589 | */ |
||
590 | public function add_payment_method_caps($caps) |
||
594 | |||
595 | |||
596 | |||
597 | } |
||
598 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.