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 Helper 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 Helper, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class Helper { |
||
15 | |||
16 | /** |
||
17 | * Create a new helper. |
||
18 | * Hook the main Carbon Fields initialization functionality. |
||
19 | */ |
||
20 | public function __construct() { |
||
35 | |||
36 | /** |
||
37 | * Load the plugin textdomain. |
||
38 | */ |
||
39 | public function load_textdomain() { |
||
46 | |||
47 | /** |
||
48 | * Register containers and fields. |
||
49 | */ |
||
50 | public function trigger_fields_register() { |
||
62 | |||
63 | /** |
||
64 | * Initialize containers. |
||
65 | */ |
||
66 | public function init_containers() { |
||
69 | |||
70 | /** |
||
71 | * Initialize main scripts |
||
72 | */ |
||
73 | public function init_scripts() { |
||
90 | |||
91 | /** |
||
92 | * Print the carbon JSON data script. |
||
93 | */ |
||
94 | public function print_json_data_script() { |
||
103 | |||
104 | /** |
||
105 | * Retrieve containers and sidebars for use in the JS. |
||
106 | * |
||
107 | * @return array $carbon_data |
||
108 | */ |
||
109 | public function get_json_data() { |
||
139 | |||
140 | /** |
||
141 | * Retrieve post meta field for a post. |
||
142 | * |
||
143 | * @param int $id Post ID. |
||
144 | * @param string $name Custom field name. |
||
145 | * @param string $type Custom field type (optional). |
||
146 | * @return mixed Meta value. |
||
147 | */ |
||
148 | public static function get_post_meta( $id, $name, $type = null ) { |
||
153 | |||
154 | /** |
||
155 | * Shorthand for get_post_meta(). |
||
156 | * Uses the ID of the current post in the loop. |
||
157 | * |
||
158 | * @param string $name Custom field name. |
||
159 | * @param string $type Custom field type (optional). |
||
160 | * @return mixed Meta value. |
||
161 | */ |
||
162 | public static function get_the_post_meta( $name, $type = null ) { |
||
165 | |||
166 | /** |
||
167 | * Retrieve theme option field value. |
||
168 | * |
||
169 | * @param string $name Custom field name. |
||
170 | * @param string $type Custom field type (optional). |
||
171 | * @return mixed Option value. |
||
172 | */ |
||
173 | public static function get_theme_option( $name, $type = null ) { |
||
176 | |||
177 | /** |
||
178 | * Retrieve term meta field for a term. |
||
179 | * |
||
180 | * @param int $id Term ID. |
||
181 | * @param string $name Custom field name. |
||
182 | * @param string $type Custom field type (optional). |
||
183 | * @return mixed Meta value. |
||
184 | */ |
||
185 | public static function get_term_meta( $id, $name, $type = null ) { |
||
190 | |||
191 | /** |
||
192 | * Retrieve user meta field for a user. |
||
193 | * |
||
194 | * @param int $id User ID. |
||
195 | * @param string $name Custom field name. |
||
196 | * @param string $type Custom field type (optional). |
||
197 | * @return mixed Meta value. |
||
198 | */ |
||
199 | public static function get_user_meta( $id, $name, $type = null ) { |
||
204 | |||
205 | /** |
||
206 | * Retrieve comment meta field for a comment. |
||
207 | * |
||
208 | * @param int $id Comment ID. |
||
209 | * @param string $name Custom field name. |
||
210 | * @param string $type Custom field type (optional). |
||
211 | * @return mixed Meta value. |
||
212 | */ |
||
213 | public static function get_comment_meta( $id, $name, $type = null ) { |
||
218 | |||
219 | /** |
||
220 | * Retrieve a certain field value from the database. |
||
221 | * Handles the logic for different field types. |
||
222 | * |
||
223 | * @param string $data_type Data type. |
||
224 | * @param string $name Custom field name. |
||
225 | * @param string $type Custom field type (optional). |
||
226 | * @param int $id ID (optional). |
||
227 | * @return mixed Meta value. |
||
228 | */ |
||
229 | public static function get_field_value( $data_type, $name, $type = null, $id = null ) { |
||
265 | |||
266 | /** |
||
267 | * Retrieve a certain field value from the database. |
||
268 | * Handles the logic for different data stores (containers). |
||
269 | * |
||
270 | * @param string $store_type Data store type. |
||
271 | * @param string $name Custom field name. |
||
272 | * @param int $id ID (optional). |
||
273 | * @return mixed Meta value. |
||
274 | */ |
||
275 | public static function get_field_value_by_store( $store_type, $name, $id = null ) { |
||
309 | |||
310 | /** |
||
311 | * Adds the field/container template(s) to the templates stack. |
||
312 | * |
||
313 | * @param object $object field or container object |
||
314 | **/ |
||
315 | public function add_templates( $object ) { |
||
333 | |||
334 | /** |
||
335 | * Build a string of concatenated pieces for an OR regex. |
||
336 | * |
||
337 | * @param array $pieces Pieces |
||
338 | * @param string $glue Glue between the pieces |
||
339 | * @return string Result string |
||
340 | */ |
||
341 | public static function preg_quote_array( $pieces, $glue = '|' ) { |
||
346 | |||
347 | /** |
||
348 | * Build the regex for parsing a certain complex field. |
||
349 | * |
||
350 | * @param string $field_name Name of the complex field. |
||
351 | * @param array $group_names Array of group names. |
||
352 | * @param array $field_names Array of subfield names. |
||
353 | * @return string Regex |
||
354 | */ |
||
355 | public static function get_complex_field_regex( $field_name, $group_names = array(), $field_names = array() ) { |
||
370 | |||
371 | /** |
||
372 | * Retrieve the complex field data for a certain field. |
||
373 | * |
||
374 | * @param string $type Datastore type. |
||
375 | * @param string $name Name of the field. |
||
376 | * @param int $id ID of the entry (optional). |
||
377 | * @return array Complex data entries. |
||
378 | */ |
||
379 | public static function get_complex_fields( $type, $name, $id = null ) { |
||
414 | |||
415 | /** |
||
416 | * Recursively expand the subfields of a complex field. |
||
417 | * |
||
418 | * @param array $input_groups Input groups. |
||
419 | * @param array $row Data row (key and value). |
||
420 | * @param array $field_name Field name pieces. |
||
421 | * @return array Expanded data. |
||
422 | */ |
||
423 | public static function expand_nested_field( $input_groups, $row, $field_name ) { |
||
441 | |||
442 | /** |
||
443 | * Parse the raw value of the relationship and association fields. |
||
444 | * |
||
445 | * @param string $raw_value Raw relationship value. |
||
446 | * @param string $type Field type. |
||
447 | * @return array Array of parsed data. |
||
448 | */ |
||
449 | public static function parse_relationship_field( $raw_value = '', $type = '' ) { |
||
483 | |||
484 | /** |
||
485 | * Detect if using the old way of storing the relationship field values. |
||
486 | * If so, parse them to the new way of storing the data. |
||
487 | * |
||
488 | * @param mixed $value Old field value. |
||
489 | * @return mixed New field value. |
||
490 | */ |
||
491 | public static function maybe_old_relationship_field( $value ) { |
||
505 | |||
506 | /** |
||
507 | * Recursive sorting function by array key. |
||
508 | * @param array &$array The input array. |
||
509 | * @param int $sort_flags Flags for controlling sorting behavior. |
||
510 | * @return array Sorted array. |
||
511 | */ |
||
512 | public static function ksort_recursive( &$array, $sort_flags = SORT_REGULAR ) { |
||
524 | } |
||
525 |
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.