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 Association_Field 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 Association_Field, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Association_Field extends Relationship_Field { |
||
17 | |||
18 | /** |
||
19 | * WP_Toolset instance |
||
20 | * @var Carbon_Fields\Toolset\WP_Toolset |
||
21 | */ |
||
22 | protected $wp_toolset; |
||
23 | |||
24 | /** |
||
25 | * Types of entries to associate with. |
||
26 | * @var array |
||
27 | */ |
||
28 | protected $types = array( |
||
29 | array( |
||
30 | 'type' => 'post', |
||
31 | 'post_type' => 'post', |
||
32 | ), |
||
33 | ); |
||
34 | |||
35 | /** |
||
36 | * Create a field from a certain type with the specified label. |
||
37 | * @param string $name Field name |
||
38 | * @param string $label Field label |
||
39 | */ |
||
40 | protected function __construct( $name, $label ) { |
||
41 | $this->wp_toolset = App::resolve( 'wp_toolset' ); |
||
42 | $this->value = new Value_Set( Value_Set::TYPE_VALUE_SET, array( 'type' => '', 'subtype' => '', 'object_id' => 0 ) ); |
||
43 | Field::__construct( $name, $label ); |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * Alias for $this->value()->set( $value ); |
||
48 | **/ |
||
49 | public function set_value( $value ) { |
||
53 | |||
54 | /** |
||
55 | * Convert a colo:separated:string into it's expected components |
||
56 | * Used for backwards compatibility to CF 1.5 |
||
57 | * |
||
58 | * @param string $value_string |
||
59 | * @return array |
||
60 | */ |
||
61 | protected function value_string_to_property_array( $value_string ) { |
||
71 | |||
72 | /** |
||
73 | * Convert a colon:separated:string into it's expected components |
||
74 | * Used for backwards compatibility to CF 1.5 |
||
75 | * |
||
76 | * @param array $value_string_array |
||
77 | * @return array<array> |
||
78 | */ |
||
79 | protected function value_string_array_to_value_set( $value_string_array ) { |
||
98 | |||
99 | /** |
||
100 | * Used to get the title of an item. |
||
101 | * |
||
102 | * Can be overriden or extended by the `carbon_association_title` filter. |
||
103 | * |
||
104 | * @param int $id The database ID of the item. |
||
105 | * @param string $type Item type (post, term, user, comment, or a custom one). |
||
106 | * @param string $subtype The subtype - "page", "post", "category", etc. |
||
107 | * @return string $title The title of the item. |
||
108 | */ |
||
109 | protected function get_title_by_type( $id, $type, $subtype = '' ) { |
||
142 | |||
143 | /** |
||
144 | * Used to get the label of an item. |
||
145 | * |
||
146 | * Can be overriden or extended by the `carbon_association_item_label` filter. |
||
147 | * |
||
148 | * @param int $id The database ID of the item. |
||
149 | * @param string $type Item type (post, term, user, comment, or a custom one). |
||
150 | * @param string $subtype Subtype - "page", "post", "category", etc. |
||
151 | * @return string $label The label of the item. |
||
152 | */ |
||
153 | protected function get_item_label( $id, $type, $subtype = '' ) { |
||
175 | |||
176 | /** |
||
177 | * Get post options |
||
178 | * |
||
179 | * @return array $options |
||
180 | */ |
||
181 | protected function get_post_options( $type ) { |
||
210 | |||
211 | /** |
||
212 | * Get term options |
||
213 | * |
||
214 | * @return array $options |
||
215 | */ |
||
216 | protected function get_term_options( $type ) { |
||
243 | |||
244 | /** |
||
245 | * Get user options |
||
246 | * |
||
247 | * @return array $options |
||
248 | */ |
||
249 | View Code Duplication | protected function get_user_options( $type ) { |
|
275 | |||
276 | /** |
||
277 | * Get comment options |
||
278 | * |
||
279 | * @return array $options |
||
280 | */ |
||
281 | View Code Duplication | protected function get_comment_options( $type ) { |
|
307 | |||
308 | /** |
||
309 | * Generate the item options. |
||
310 | * |
||
311 | * @return array $options The selectable options of the association field. |
||
312 | */ |
||
313 | public function get_options() { |
||
334 | |||
335 | /** |
||
336 | * Retrieve the edit link of a particular object. |
||
337 | * |
||
338 | * @param string $type Object type. |
||
339 | * @param int $id ID of the object. |
||
340 | * @return string URL of the edit link. |
||
341 | */ |
||
342 | protected function get_object_edit_link( $type, $id ) { |
||
368 | |||
369 | /** |
||
370 | * Modify the types. |
||
371 | * @param array $types New types |
||
372 | */ |
||
373 | public function set_types( $types ) { |
||
377 | |||
378 | /** |
||
379 | * Converts the field values into a usable associative array. |
||
380 | * |
||
381 | * The association data is saved in the database in the following format: |
||
382 | * array ( |
||
383 | * 0 => 'post:page:4', |
||
384 | * 1 => 'term:category:2', |
||
385 | * 2 => 'user:user:1', |
||
386 | * ) |
||
387 | * where the value of each array item contains: |
||
388 | * - Type of data (post, term, user or comment) |
||
389 | * - Subtype of data (the particular post type or taxonomy) |
||
390 | * - ID of the item (the database ID of the item) |
||
391 | */ |
||
392 | protected function value_to_json() { |
||
408 | |||
409 | /** |
||
410 | * Convert the field data into JSON representation. |
||
411 | * @param bool $load Whether to load data from the datastore. |
||
412 | * @return mixed The JSON field data. |
||
413 | */ |
||
414 | public function to_json( $load ) { |
||
433 | |||
434 | /** |
||
435 | * Serves as a backbone template for the association items. |
||
436 | * Used for both the selected and the selectable options. |
||
437 | * |
||
438 | * @param bool $display_input Whether to display the selected item input field. |
||
439 | */ |
||
440 | public function item_template( $display_input = true ) { |
||
461 | } |
||
462 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.