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 WPInv_Item 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 WPInv_Item, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
5 | class WPInv_Item { |
||
6 | public $ID = 0; |
||
7 | private $price; |
||
8 | private $vat_rule; |
||
9 | private $vat_class; |
||
10 | private $type; |
||
11 | |||
12 | public $post_author = 0; |
||
13 | public $post_date = '0000-00-00 00:00:00'; |
||
14 | public $post_date_gmt = '0000-00-00 00:00:00'; |
||
15 | public $post_content = ''; |
||
16 | public $post_title = ''; |
||
17 | public $post_excerpt = ''; |
||
18 | public $post_status = 'publish'; |
||
19 | public $comment_status = 'open'; |
||
20 | public $ping_status = 'open'; |
||
21 | public $post_password = ''; |
||
22 | public $post_name = ''; |
||
23 | public $to_ping = ''; |
||
24 | public $pinged = ''; |
||
25 | public $post_modified = '0000-00-00 00:00:00'; |
||
26 | public $post_modified_gmt = '0000-00-00 00:00:00'; |
||
27 | public $post_content_filtered = ''; |
||
28 | public $post_parent = 0; |
||
29 | public $guid = ''; |
||
30 | public $menu_order = 0; |
||
31 | public $post_mime_type = ''; |
||
32 | public $comment_count = 0; |
||
33 | public $filter; |
||
34 | |||
35 | |||
36 | public function __construct( $_id = false, $_args = array() ) { |
||
40 | |||
41 | private function setup_item( $item ) { |
||
64 | |||
65 | public function __get( $key ) { |
||
66 | if ( method_exists( $this, 'get_' . $key ) ) { |
||
67 | return call_user_func( array( $this, 'get_' . $key ) ); |
||
68 | } else { |
||
69 | return new WP_Error( 'wpinv-item-invalid-property', sprintf( __( 'Can\'t get property %s', 'invoicing' ), $key ) ); |
||
70 | } |
||
71 | } |
||
72 | |||
73 | public function create( $data = array(), $wp_error = false ) { |
||
74 | if ( $this->ID != 0 ) { |
||
75 | return false; |
||
76 | } |
||
77 | |||
78 | $defaults = array( |
||
79 | 'post_type' => 'wpi_item', |
||
80 | 'post_status' => 'draft', |
||
81 | 'post_title' => __( 'New Invoice Item', 'invoicing' ) |
||
82 | ); |
||
83 | |||
84 | $args = wp_parse_args( $data, $defaults ); |
||
85 | |||
86 | do_action( 'wpinv_item_pre_create', $args ); |
||
87 | |||
88 | $id = wp_insert_post( $args, $wp_error ); |
||
89 | if ($wp_error && is_wp_error($id)) { |
||
90 | return $id; |
||
91 | } |
||
92 | if ( !$id ) { |
||
93 | return false; |
||
94 | } |
||
95 | |||
96 | $item = WP_Post::get_instance( $id ); |
||
97 | |||
98 | View Code Duplication | if (!empty($item) && !empty($data['meta'])) { |
|
99 | $this->ID = $item->ID; |
||
100 | $this->save_metas($data['meta']); |
||
101 | } |
||
102 | |||
103 | // Set custom id if not set. |
||
104 | if ( empty( $data['meta']['custom_id'] ) && !$this->get_custom_id() ) { |
||
105 | $this->save_metas( array( 'custom_id' => $id ) ); |
||
106 | } |
||
107 | |||
108 | do_action( 'wpinv_item_create', $id, $args ); |
||
109 | |||
110 | return $this->setup_item( $item ); |
||
111 | } |
||
112 | |||
113 | public function update( $data = array(), $wp_error = false ) { |
||
114 | if ( !$this->ID > 0 ) { |
||
115 | return false; |
||
116 | } |
||
117 | |||
118 | $data['ID'] = $this->ID; |
||
119 | |||
120 | do_action( 'wpinv_item_pre_update', $data ); |
||
121 | |||
122 | $id = wp_update_post( $data, $wp_error ); |
||
123 | if ($wp_error && is_wp_error($id)) { |
||
124 | return $id; |
||
125 | } |
||
126 | |||
127 | if ( !$id ) { |
||
128 | return false; |
||
129 | } |
||
130 | |||
131 | $item = WP_Post::get_instance( $id ); |
||
132 | View Code Duplication | if (!empty($item) && !empty($data['meta'])) { |
|
133 | $this->ID = $item->ID; |
||
134 | $this->save_metas($data['meta']); |
||
135 | } |
||
136 | |||
137 | // Set custom id if not set. |
||
138 | if ( empty( $data['meta']['custom_id'] ) && !$this->get_custom_id() ) { |
||
139 | $this->save_metas( array( 'custom_id' => $id ) ); |
||
140 | } |
||
141 | |||
142 | do_action( 'wpinv_item_update', $id, $data ); |
||
143 | |||
144 | return $this->setup_item( $item ); |
||
145 | } |
||
146 | |||
147 | public function get_ID() { |
||
150 | |||
151 | public function get_name() { |
||
154 | |||
155 | public function get_summary() { |
||
158 | |||
159 | public function get_price() { |
||
172 | |||
173 | public function get_the_price() { |
||
178 | |||
179 | View Code Duplication | public function get_vat_rule() { |
|
192 | |||
193 | View Code Duplication | public function get_vat_class() { |
|
204 | |||
205 | View Code Duplication | public function get_type() { |
|
216 | |||
217 | public function get_custom_id() { |
||
222 | |||
223 | public function get_custom_name() { |
||
228 | |||
229 | public function get_custom_singular_name() { |
||
234 | |||
235 | public function is_recurring() { |
||
241 | |||
242 | View Code Duplication | public function get_recurring_period( $full = false ) { |
|
269 | |||
270 | public function get_recurring_interval() { |
||
280 | |||
281 | public function get_recurring_limit() { |
||
287 | |||
288 | public function has_free_trial() { |
||
295 | |||
296 | View Code Duplication | public function get_trial_period( $full = false ) { |
|
323 | |||
324 | public function get_trial_interval() { |
||
334 | |||
335 | public function is_free() { |
||
347 | |||
348 | public function is_package() { |
||
354 | |||
355 | public function is_editable() { |
||
356 | $editable = get_post_meta( $this->ID, '_wpinv_editable', true ); |
||
357 | |||
362 | |||
363 | public function save_metas( $metas = array() ) { |
||
376 | |||
377 | public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) { |
||
386 | |||
387 | public function get_fees( $type = 'fee', $item_id = 0 ) { |
||
429 | |||
430 | public function can_purchase() { |
||
439 | } |
||
440 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.