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 wpshop_categories 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 wpshop_categories, and based on these observations, apply Extract Interface, too.
1 | <?php if ( !defined( 'ABSPATH' ) ) exit; |
||
24 | class wpshop_categories |
||
25 | { |
||
26 | /** |
||
27 | * Retourne une liste de cat�gorie |
||
28 | * @param boolean $formated : formatage du r�sultat oui/non |
||
29 | * @param string $product_search : recherche demand�e |
||
30 | * @return mixed |
||
31 | **/ |
||
32 | public static function product_list_cats($formated=false, $product_search=null) { |
||
55 | |||
56 | /** |
||
57 | * Call wordpress function that declare a new term type in order to define the product as wordpress term (taxonomy) |
||
58 | */ |
||
59 | public static function create_product_categories(){ |
||
89 | |||
90 | /** |
||
91 | * Build a complete tree with the categories. Contains the complete tree for a given category and a children list for easy checking |
||
92 | * |
||
93 | * @param integer $category_id The category identifier we want to get the tree element for |
||
94 | * |
||
95 | * @return array $categories_list An array ordered by category with its children |
||
96 | */ |
||
97 | public static function category_tree($category_id = 0){ |
||
117 | /** |
||
118 | * Get the sub categories of a given category |
||
119 | * |
||
120 | * @param integer $parent_category The main category we want to have the sub categories for |
||
121 | * @param array $instance The current instance of the widget, allows to get the different selected parameters |
||
122 | * |
||
123 | * @return mixed $widget_content The widget content build from option |
||
124 | */ |
||
125 | public static function category_tree_output($category_id = 0, $instance) { |
||
148 | |||
149 | |||
150 | /** |
||
151 | * Add additionnal fields to the category edition form |
||
152 | */ |
||
153 | public static function category_edit_fields(){ |
||
154 | $category_id = (int) $_REQUEST["tag_ID"]; |
||
155 | $category_meta_information = get_option(WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES . '_' . $category_id); |
||
156 | $tpl_component = array(); |
||
157 | wp_enqueue_media(); |
||
158 | $category_thumbnail_preview = '<img src="' .WPSHOP_DEFAULT_CATEGORY_PICTURE. '" alt="No picture" class="category_thumbnail_preview" />'; |
||
159 | /* Check if there is already a picture for the selected category */ |
||
160 | |||
161 | View Code Duplication | if ( !empty($category_meta_information['wpshop_category_picture']) ) { |
|
162 | $image_post = wp_get_attachment_image( $category_meta_information['wpshop_category_picture'], 'thumbnail', false, array('class' => 'category_thumbnail_preview') ); |
||
163 | $category_thumbnail_preview = ( !empty($image_post) ) ? $image_post : '<img src="' .WPSHOP_DEFAULT_CATEGORY_PICTURE. '" alt="No picture" class="category_thumbnail_preview" />'; |
||
164 | } |
||
165 | |||
166 | |||
167 | $tpl_component['CATEGORY_DELETE_PICTURE_BUTTON'] = ''; |
||
168 | if( !empty($category_meta_information) && !empty($category_meta_information['wpshop_category_picture']) ) { |
||
169 | $tpl_component['CATEGORY_DELETE_PICTURE_BUTTON'] = '<a href="#" role="button" id="wps-delete-category-picture" data-nonce="' . wp_create_nonce( 'wps_delete_picture_category' ) . '" class="wps-bton-second-mini-rounded">' .__( 'Delete the category picture', 'wpshop' ). '</a> '; |
||
170 | } |
||
171 | $tpl_component['CATEGORY_PICTURE_ID'] = ( ( !empty($category_meta_information['wpshop_category_picture']) ) ? $category_meta_information['wpshop_category_picture'] : '' ); |
||
172 | |||
173 | $tpl_component['CATEGORY_THUMBNAIL_PREVIEW'] = $category_thumbnail_preview; |
||
174 | if(isset($category_id)){ |
||
175 | $tpl_component['CATEGORY_TAG_ID'] = $category_id; |
||
176 | $tpl_component['CATEGORY_FILTERABLE_ATTRIBUTES'] = ''; |
||
177 | $wpshop_category_products = wpshop_categories::get_product_of_category( $category_id ); |
||
178 | $filterable_attributes_list = array(); |
||
179 | foreach ( $wpshop_category_products as $wpshop_category_product ) { |
||
180 | $elementId = wpshop_entities::get_entity_identifier_from_code(WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT); |
||
181 | if ( !empty($elementId) ) { |
||
182 | $product_attributes = wpshop_attributes::get_attribute_list_for_item($elementId, $wpshop_category_product); |
||
183 | if ( !empty($product_attributes) ) { |
||
184 | foreach ( $product_attributes as $key => $product_attribute ) { |
||
185 | if ( !empty($product_attribute) && !empty($product_attribute->is_filterable) && strtolower(__($product_attribute->is_filterable, 'wpshop')) == strtolower(__('Yes', 'wpshop')) ) { |
||
186 | if ( !array_key_exists($product_attribute->attribute_id, $filterable_attributes_list) ) { |
||
187 | $filterable_attributes_list[$product_attribute->attribute_id] = $product_attribute; |
||
188 | $sub_tpl_component['CATEGORY_FILTERABLE_ATTRIBUTE_ID'] = $product_attribute->attribute_id; |
||
189 | $sub_tpl_component['CATEGORY_FILTERABLE_ATTRIBUTE_NAME'] = __($product_attribute->frontend_label, 'wpshop'); |
||
190 | if ( !empty($category_meta_information) && !empty($category_meta_information['wpshop_category_filterable_attributes']) && array_key_exists($product_attribute->attribute_id, $category_meta_information['wpshop_category_filterable_attributes']) ) { |
||
191 | $sub_tpl_component['CATEGORY_FILTERABLE_ATTRIBUTE_CHECKED'] = 'checked="checked"'; |
||
192 | } |
||
193 | else { |
||
194 | $sub_tpl_component['CATEGORY_FILTERABLE_ATTRIBUTE_CHECKED'] = ''; |
||
195 | } |
||
196 | |||
197 | $tpl_component['CATEGORY_FILTERABLE_ATTRIBUTES'] .= wpshop_display::display_template_element('wpshop_category_filterable_attribute_element', $sub_tpl_component, array(), 'admin'); |
||
198 | unset($sub_tpl_component); |
||
199 | } |
||
200 | } |
||
201 | } |
||
202 | } |
||
203 | } |
||
204 | } |
||
205 | } |
||
206 | else { |
||
207 | $tpl_component['CATEGORY_TAG_ID'] = 1; |
||
208 | } |
||
209 | $output = wpshop_display::display_template_element('wpshop_category_edit_interface_admin', $tpl_component, array(), 'admin'); |
||
210 | echo $output; |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Save the different extra fields added for the plugin |
||
215 | * |
||
216 | * @param integer $category_id The category identifier we want to save extra fields for |
||
217 | * @param mixed $tt_id |
||
218 | * |
||
219 | * @return void |
||
220 | */ |
||
221 | public static function category_fields_saver($category_id, $tt_id){ |
||
222 | global $wpdb; |
||
223 | $category_meta = array(); |
||
224 | $category_option = get_option( WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES . '_' . $category_id); |
||
225 | |||
226 | $wps_category_picture_id = !empty($_POST['wps_category_picture_id']) ? (int) $_POST['wps_category_picture_id'] : null; |
||
227 | $filterable_attribute_for_category = ( !empty($_POST['filterable_attribute_for_category']) && is_array($_POST['filterable_attribute_for_category']) ) ? (array) $_POST['filterable_attribute_for_category'] : null; |
||
228 | |||
229 | if ( isset( $wps_category_picture_id ) ) { |
||
230 | $attach_id = intval( $wps_category_picture_id ); |
||
231 | $category_option['wpshop_category_picture'] = $attach_id; |
||
232 | } |
||
233 | |||
234 | if ( isset( $filterable_attribute_for_category ) ) { |
||
235 | $category_option['wpshop_category_filterable_attributes'] = $filterable_attribute_for_category; |
||
236 | } |
||
237 | else { |
||
238 | $category_option['wpshop_category_filterable_attributes'] = array(); |
||
239 | } |
||
240 | update_option(WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES . '_' . $category_id, $category_option); |
||
241 | |||
242 | /** Update filter values **/ |
||
243 | $wpshop_filter_search = new wps_filter_search(); |
||
244 | $wpshop_filter_search->stock_values_for_attribute( array($category_id) ); |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Add extra column to categories listing interface |
||
249 | * |
||
250 | * @param array $columns Actual columns to add extra columns to |
||
251 | * |
||
252 | * @return array $columns The new array with additionnal colu |
||
253 | */ |
||
254 | public static function category_manage_columns($columns){ |
||
266 | |||
267 | /** |
||
268 | * Define the content of extra columns to add to categories listing interface |
||
269 | */ |
||
270 | public static function category_manage_columns_content($string, $column_name, $category_id){ |
||
284 | |||
285 | |||
286 | /** |
||
287 | * Display a category in a list |
||
288 | * |
||
289 | * @param object $category The category definition |
||
290 | * @param string $output_type The output type defined from plugin option |
||
291 | * |
||
292 | * @return mixed $content Output the category list |
||
293 | */ |
||
294 | public static function category_mini_output($category, $output_type = 'list'){ |
||
352 | |||
353 | /** |
||
354 | * Traduit le shortcode et affiche une cat�gorie |
||
355 | * @param array $atts : tableau de param�tre du shortcode |
||
356 | * @return mixed |
||
357 | **/ |
||
358 | public static function wpshop_category_func($atts) { |
||
359 | global $wpdb; |
||
360 | $string = ''; |
||
361 | if ( !empty($atts['cid']) ) { |
||
362 | $atts['type'] = (!empty($atts['type']) && in_array($atts['type'],array('grid','list'))) ? $atts['type'] : 'grid'; |
||
363 | |||
364 | $cat_list = explode(',', $atts['cid']); |
||
365 | |||
366 | if ( (count($cat_list) > 1) || ( !empty($atts['display']) && ($atts['display'] == 'only_cat') ) ) { |
||
367 | if( count($cat_list) == 1) { |
||
368 | $args = array('taxonomy' => WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES, 'parent' => $cat_list[0]); |
||
369 | $categories = get_terms( $args ); |
||
370 | foreach($categories as $category) { |
||
371 | $cat_list[] = $category->term_id; |
||
372 | } |
||
373 | } |
||
374 | $string .= ' |
||
375 | <div class="wpshop_categories_' . $atts['type'] . '" >'; |
||
376 | foreach( $cat_list as $cat_id ){ |
||
377 | $sub_category_def = get_term($cat_id, WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES); |
||
378 | $string .= wpshop_categories::category_mini_output($sub_category_def, $atts['type']); |
||
379 | } |
||
380 | $string .= ' |
||
381 | </div>'; |
||
382 | } |
||
383 | else { |
||
384 | $sub_category_def = get_term($atts['cid'], WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES); |
||
385 | |||
386 | if ( empty($atts['display']) || ($atts['display'] != 'only_products') ){ |
||
387 | $string .= wpshop_categories::category_mini_output($sub_category_def, $atts['type']); |
||
388 | $string .= ' |
||
389 | <div class="category_product_' . $atts['type'] . '" > |
||
390 | <h2 class="category_content_part_title" >'.__('Category\'s product list', 'wpshop').'</h2>'; |
||
391 | } |
||
392 | |||
393 | $string .= wpshop_products::wpshop_products_func($atts); |
||
394 | |||
395 | if ( empty($atts['display']) || ($atts['display'] != 'only_products') ){ |
||
396 | $string .= '</div>'; |
||
397 | } |
||
398 | } |
||
399 | } |
||
400 | else { |
||
401 | $string .= __('No categories found for display', 'wpshop'); |
||
402 | } |
||
403 | |||
404 | return do_shortcode($string); |
||
405 | } |
||
406 | |||
407 | public static function get_product_of_category( $category_id ) { |
||
421 | |||
422 | /** |
||
423 | * Get the category thumbnail by the category id. Get the option |
||
424 | * wpshop_product_category_$id, check if the option is an array and if the key |
||
425 | * wpshop_category_picture(id post value) it's not empty, if it is the case set the |
||
426 | * previously value in $id_picture. Use wp_get_attachment_image_src with the |
||
427 | * $id_picture for get the informations of attachment like: url, with, height and |
||
428 | * resized image (true for resized image, false if it is the original). |
||
429 | * |
||
430 | * @see get_option |
||
431 | * @see wp_get_attachment_image_src |
||
432 | * @param unknown_type $id |
||
433 | * @param unknown_type $size |
||
434 | * @param unknown_type $attr |
||
435 | * @return (string or array) |
||
436 | */ |
||
437 | public static function get_the_category_thumbnail($id, $size = 'thumbnail', $icon = false) { |
||
459 | } |
||
460 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.