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 Auto_Load_Next_Post_Admin_Settings 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 Auto_Load_Next_Post_Admin_Settings, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class ALNP_Admin_Settings { |
||
21 | |||
22 | /** |
||
23 | * Setting pages. |
||
24 | * |
||
25 | * @access private |
||
26 | * @static |
||
27 | * @var array |
||
28 | */ |
||
29 | private static $settings = array(); |
||
30 | |||
31 | /** |
||
32 | * Error messages. |
||
33 | * |
||
34 | * @access private |
||
35 | * @static |
||
36 | * @var array |
||
37 | */ |
||
38 | private static $errors = array(); |
||
39 | |||
40 | /** |
||
41 | * Update messages. |
||
42 | * |
||
43 | * @access private |
||
44 | * @static |
||
45 | * @var array |
||
46 | */ |
||
47 | private static $messages = array(); |
||
48 | |||
49 | /** |
||
50 | * Include the settings page classes. |
||
51 | * |
||
52 | * @access public |
||
53 | * @static |
||
54 | * @since 1.0.0 |
||
55 | * @version 1.6.0 |
||
56 | * @return $settings |
||
57 | */ |
||
58 | public static function get_settings_pages() { |
||
74 | |||
75 | /** |
||
76 | * Save the settings. |
||
77 | * |
||
78 | * @access public |
||
79 | * @static |
||
80 | * @since 1.0.0 |
||
81 | * @version 1.6.0 |
||
82 | * @global $current_view |
||
83 | */ |
||
84 | public static function save() { |
||
98 | |||
99 | /** |
||
100 | * Add a message |
||
101 | * |
||
102 | * @access public |
||
103 | * @static |
||
104 | * @since 1.0.0 |
||
105 | * @param string $text Message |
||
106 | */ |
||
107 | public static function add_message( $text ) { |
||
110 | |||
111 | /** |
||
112 | * Add an error |
||
113 | * |
||
114 | * @access public |
||
115 | * @static |
||
116 | * @since 1.0.0 |
||
117 | * @param string $text Error |
||
118 | */ |
||
119 | public static function add_error( $text ) { |
||
122 | |||
123 | /** |
||
124 | * Output messages and errors. |
||
125 | * |
||
126 | * @access public |
||
127 | * @static |
||
128 | * @since 1.0.0 |
||
129 | * @version 1.6.0 |
||
130 | * @return string |
||
131 | */ |
||
132 | public static function show_messages() { |
||
143 | |||
144 | /** |
||
145 | * Settings Page. |
||
146 | * |
||
147 | * Handles the display of the main settings page in admin. |
||
148 | * |
||
149 | * @access public |
||
150 | * @static |
||
151 | * @since 1.0.0 |
||
152 | * @version 1.6.0 |
||
153 | * @global $current_view |
||
154 | * @return void |
||
155 | */ |
||
156 | public static function output() { |
||
174 | |||
175 | /** |
||
176 | * Get a setting from the settings API. |
||
177 | * |
||
178 | * @access public |
||
179 | * @static |
||
180 | * @since 1.0.0 |
||
181 | * @param mixed $option_name |
||
182 | * @return string |
||
183 | */ |
||
184 | public static function get_option( $option_name, $default = '' ) { |
||
215 | |||
216 | /** |
||
217 | * Output admin fields. |
||
218 | * |
||
219 | * Loops though the plugin options array and outputs each field. |
||
220 | * |
||
221 | * @access public |
||
222 | * @static |
||
223 | * @since 1.0.0 |
||
224 | * @version 1.6.0 |
||
225 | * @param array $options Opens array to output |
||
226 | */ |
||
227 | public static function output_fields( $options ) { |
||
534 | |||
535 | /** |
||
536 | * Save admin fields. |
||
537 | * |
||
538 | * Loops though the plugin options array and outputs each field. |
||
539 | * |
||
540 | * @access public |
||
541 | * @static |
||
542 | * @since 1.0.0 |
||
543 | * @version 1.5.0 |
||
544 | * @param array $options Opens array to output |
||
545 | * @return bool |
||
546 | */ |
||
547 | public static function save_fields( $options ) { |
||
548 | if ( empty( $_POST ) ) { |
||
549 | return false; |
||
550 | } |
||
551 | |||
552 | // Options to update will be stored here |
||
553 | $update_options = array(); |
||
554 | $autoload_options = array(); |
||
555 | |||
556 | // Loop options and get values to save |
||
557 | foreach ( $options as $option ) { |
||
558 | if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) { |
||
559 | continue; |
||
560 | } |
||
561 | |||
562 | // Get posted value. |
||
563 | if ( strstr( $option['id'], '[' ) ) { |
||
564 | parse_str( $option['id'], $option_name_array ); |
||
565 | $option_name = current( array_keys( $option_name_array ) ); |
||
566 | $setting_name = key( $option_name_array[ $option_name ] ); |
||
567 | $raw_value = isset( $_POST[ $option_name ][ $setting_name ] ) ? wp_unslash( $_POST[ $option_name ][ $setting_name ] ) : null; |
||
568 | } else { |
||
569 | $option_name = $option['id']; |
||
570 | $setting_name = ''; |
||
571 | $raw_value = isset( $_POST[ $option['id'] ] ) ? wp_unslash( $_POST[ $option['id'] ] ) : null; |
||
572 | } |
||
573 | |||
574 | switch ( $option['type'] ) { |
||
575 | case "checkbox" : |
||
576 | $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no'; |
||
577 | break; |
||
578 | |||
579 | case "textarea" : |
||
580 | $value = wp_kses_post( trim( stripslashes( $_POST[$option['id']] ) ) ); |
||
581 | break; |
||
582 | |||
583 | case "multiselect" : |
||
584 | $value = array_filter( array_map( 'auto_load_next_post_clean', (array) $raw_value ) ); |
||
585 | break; |
||
586 | |||
587 | case 'select' : |
||
588 | $allowed_values = empty( $option['options'] ) ? array() : array_map( 'strval', array_keys( $option['options'] ) ); |
||
589 | if ( empty( $option['default'] ) && empty( $allowed_values ) ) { |
||
590 | $value = null; |
||
591 | break; |
||
592 | } |
||
593 | $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] ); |
||
594 | $value = in_array( $raw_value, $allowed_values, true ) ? $raw_value : $default; |
||
595 | break; |
||
596 | |||
597 | default : |
||
598 | $value = auto_load_next_post_clean( $raw_value ); |
||
599 | break; |
||
600 | } // END switch() |
||
601 | |||
602 | /** |
||
603 | * Fire an action when a certain 'type' of field is being saved. |
||
604 | * |
||
605 | * @deprecated 1.5.0 - doesn't allow manipulation of values! |
||
606 | */ |
||
607 | if ( has_action( 'auto_load_next_post_update_option_' . sanitize_title( $option['type'] ) ) ) { |
||
608 | if ( is_ajax() ) { |
||
609 | error_log( 'auto_load_next_post_update_option_' . sanitize_title( $option['type'] ) . ' is deprecated since version 1.5.0' ); |
||
610 | } else { |
||
611 | _deprecated_hook( 'auto_load_next_post_update_option_' . sanitize_title( $option['type'] ), '1.5.0' ); |
||
612 | } |
||
613 | |||
614 | do_action( 'auto_load_next_post_update_option_' . sanitize_title( $option['type'] ), $option ); |
||
615 | continue; |
||
616 | } |
||
617 | |||
618 | if ( is_null( $value ) ) { |
||
619 | continue; |
||
620 | } |
||
621 | |||
622 | // Check if option is an array and handle that differently to single values. |
||
623 | if ( $option_name && $setting_name ) { |
||
624 | if ( ! isset( $update_options[ $option_name ] ) ) { |
||
625 | $update_options[ $option_name ] = get_option( $option_name, array() ); |
||
626 | } |
||
627 | if ( ! is_array( $update_options[ $option_name ] ) ) { |
||
628 | $update_options[ $option_name ] = array(); |
||
629 | } |
||
630 | $update_options[ $option_name ][ $setting_name ] = $value; |
||
631 | } else { |
||
632 | $update_options[ $option_name ] = $value; |
||
633 | } |
||
634 | |||
635 | $autoload_options[ $option_name ] = isset( $option['autoload'] ) ? (bool) $option['autoload'] : true; |
||
636 | |||
637 | /** |
||
638 | * Fire an action before saved. |
||
639 | * |
||
640 | * @deprecated 1.5.0 - doesn't allow manipulation of values! |
||
641 | */ |
||
642 | if ( has_action( 'auto_load_next_post_update_option' ) ) { |
||
643 | if ( is_ajax() ) { |
||
644 | error_log( 'auto_load_next_post_update_option is deprecated since version 1.5.0' ); |
||
645 | } else { |
||
646 | _deprecated_hook( 'auto_load_next_post_update_option', '1.5.0' ); |
||
647 | } |
||
667 |