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 Custom_Background 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 Custom_Background, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Custom_Background { |
||
17 | |||
18 | /** |
||
19 | * Callback for administration header. |
||
20 | * |
||
21 | * @var callable |
||
22 | * @since 3.0.0 |
||
23 | */ |
||
24 | public $admin_header_callback; |
||
25 | |||
26 | /** |
||
27 | * Callback for header div. |
||
28 | * |
||
29 | * @var callable |
||
30 | * @since 3.0.0 |
||
31 | */ |
||
32 | public $admin_image_div_callback; |
||
33 | |||
34 | /** |
||
35 | * Used to trigger a success message when settings updated and set to true. |
||
36 | * |
||
37 | * @since 3.0.0 |
||
38 | * @access private |
||
39 | * @var bool |
||
40 | */ |
||
41 | private $updated; |
||
42 | |||
43 | /** |
||
44 | * Constructor - Register administration header callback. |
||
45 | * |
||
46 | * @since 3.0.0 |
||
47 | * @param callable $admin_header_callback |
||
48 | * @param callable $admin_image_div_callback Optional custom image div output callback. |
||
49 | */ |
||
50 | public function __construct($admin_header_callback = '', $admin_image_div_callback = '') { |
||
61 | |||
62 | /** |
||
63 | * Set up the hooks for the Custom Background admin page. |
||
64 | * |
||
65 | * @since 3.0.0 |
||
66 | */ |
||
67 | public function init() { |
||
81 | |||
82 | /** |
||
83 | * Set up the enqueue for the CSS & JavaScript files. |
||
84 | * |
||
85 | * @since 3.0.0 |
||
86 | */ |
||
87 | public function admin_load() { |
||
108 | |||
109 | /** |
||
110 | * Execute custom background modification. |
||
111 | * |
||
112 | * @since 3.0.0 |
||
113 | */ |
||
114 | public function take_action() { |
||
216 | |||
217 | /** |
||
218 | * Display the custom background page. |
||
219 | * |
||
220 | * @since 3.0.0 |
||
221 | */ |
||
222 | public function admin_page() { |
||
223 | ?> |
||
224 | <div class="wrap" id="custom-background"> |
||
225 | <h1><?php _e( 'Custom Background' ); ?></h1> |
||
226 | |||
227 | <?php if ( current_user_can( 'customize' ) ) { ?> |
||
228 | <div class="notice notice-info hide-if-no-customize"> |
||
229 | <p> |
||
230 | <?php |
||
231 | printf( |
||
232 | __( 'You can now manage and live-preview Custom Backgrounds in the <a href="%1$s">Customizer</a>.' ), |
||
233 | admin_url( 'customize.php?autofocus[control]=background_image' ) |
||
234 | ); |
||
235 | ?> |
||
236 | </p> |
||
237 | </div> |
||
238 | <?php } ?> |
||
239 | |||
240 | <?php if ( ! empty( $this->updated ) ) { ?> |
||
241 | <div id="message" class="updated"> |
||
242 | <p><?php printf( __( 'Background updated. <a href="%s">Visit your site</a> to see how it looks.' ), home_url( '/' ) ); ?></p> |
||
243 | </div> |
||
244 | <?php } ?> |
||
245 | |||
246 | <h3><?php _e( 'Background Image' ); ?></h3> |
||
247 | |||
248 | <table class="form-table"> |
||
249 | <tbody> |
||
250 | <tr> |
||
251 | <th scope="row"><?php _e( 'Preview' ); ?></th> |
||
252 | <td> |
||
253 | <?php |
||
254 | if ( $this->admin_image_div_callback ) { |
||
255 | call_user_func( $this->admin_image_div_callback ); |
||
256 | } else { |
||
257 | $background_styles = ''; |
||
258 | if ( $bgcolor = get_background_color() ) |
||
259 | $background_styles .= 'background-color: #' . $bgcolor . ';'; |
||
260 | |||
261 | $background_image_thumb = get_background_image(); |
||
262 | if ( $background_image_thumb ) { |
||
263 | $background_image_thumb = esc_url( set_url_scheme( get_theme_mod( 'background_image_thumb', str_replace( '%', '%%', $background_image_thumb ) ) ) ); |
||
264 | $background_position_x = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ); |
||
265 | $background_position_y = get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) ); |
||
266 | $background_size = get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ); |
||
267 | $background_repeat = get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ); |
||
268 | $background_attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ); |
||
269 | |||
270 | // Background-image URL must be single quote, see below. |
||
271 | $background_styles .= " background-image: url('$background_image_thumb');" |
||
272 | . " background-size: $background_size;" |
||
273 | . " background-position: $background_position_x $background_position_y;" |
||
274 | . " background-repeat: $background_repeat;" |
||
275 | . " background-attachment: $background_attachment;"; |
||
276 | } |
||
277 | ?> |
||
278 | <div id="custom-background-image" style="<?php echo $background_styles; ?>"><?php // must be double quote, see above ?> |
||
279 | <?php if ( $background_image_thumb ) { ?> |
||
280 | <img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" /><br /> |
||
281 | <img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" /> |
||
282 | <?php } ?> |
||
283 | </div> |
||
284 | <?php } ?> |
||
285 | </td> |
||
286 | </tr> |
||
287 | |||
288 | <?php if ( get_background_image() ) : ?> |
||
289 | <tr> |
||
290 | <th scope="row"><?php _e('Remove Image'); ?></th> |
||
291 | <td> |
||
292 | <form method="post"> |
||
293 | <?php wp_nonce_field('custom-background-remove', '_wpnonce-custom-background-remove'); ?> |
||
294 | <?php submit_button( __( 'Remove Background Image' ), '', 'remove-background', false ); ?><br/> |
||
295 | <?php _e('This will remove the background image. You will not be able to restore any customizations.') ?> |
||
296 | </form> |
||
297 | </td> |
||
298 | </tr> |
||
299 | <?php endif; ?> |
||
300 | |||
301 | <?php $default_image = get_theme_support( 'custom-background', 'default-image' ); ?> |
||
302 | View Code Duplication | <?php if ( $default_image && get_background_image() != $default_image ) : ?> |
|
303 | <tr> |
||
304 | <th scope="row"><?php _e('Restore Original Image'); ?></th> |
||
305 | <td> |
||
306 | <form method="post"> |
||
307 | <?php wp_nonce_field('custom-background-reset', '_wpnonce-custom-background-reset'); ?> |
||
308 | <?php submit_button( __( 'Restore Original Image' ), '', 'reset-background', false ); ?><br/> |
||
309 | <?php _e('This will restore the original background image. You will not be able to restore any customizations.') ?> |
||
310 | </form> |
||
311 | </td> |
||
312 | </tr> |
||
313 | <?php endif; ?> |
||
314 | |||
315 | <?php if ( current_user_can( 'upload_files' ) ): ?> |
||
316 | <tr> |
||
317 | <th scope="row"><?php _e('Select Image'); ?></th> |
||
318 | <td><form enctype="multipart/form-data" id="upload-form" class="wp-upload-form" method="post"> |
||
319 | <p> |
||
320 | <label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br /> |
||
321 | <input type="file" id="upload" name="import" /> |
||
322 | <input type="hidden" name="action" value="save" /> |
||
323 | <?php wp_nonce_field( 'custom-background-upload', '_wpnonce-custom-background-upload' ); ?> |
||
324 | <?php submit_button( __( 'Upload' ), '', 'submit', false ); ?> |
||
325 | </p> |
||
326 | <p> |
||
327 | <label for="choose-from-library-link"><?php _e( 'Or choose an image from your media library:' ); ?></label><br /> |
||
328 | <button id="choose-from-library-link" class="button" |
||
329 | data-choose="<?php esc_attr_e( 'Choose a Background Image' ); ?>" |
||
330 | data-update="<?php esc_attr_e( 'Set as background' ); ?>"><?php _e( 'Choose Image' ); ?></button> |
||
331 | </p> |
||
332 | </form> |
||
333 | </td> |
||
334 | </tr> |
||
335 | <?php endif; ?> |
||
336 | </tbody> |
||
337 | </table> |
||
338 | |||
339 | <h3><?php _e( 'Display Options' ); ?></h3> |
||
340 | <form method="post"> |
||
341 | <table class="form-table"> |
||
342 | <tbody> |
||
343 | <?php if ( get_background_image() ) : ?> |
||
344 | <input name="background-preset" type="hidden" value="custom"> |
||
345 | |||
346 | <?php |
||
347 | $background_position = sprintf( |
||
348 | '%s %s', |
||
349 | get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ), |
||
350 | get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) ) |
||
351 | ); |
||
352 | |||
353 | $background_position_options = array( |
||
354 | array( |
||
355 | 'left top' => array( 'label' => __( 'Top Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ), |
||
356 | 'center top' => array( 'label' => __( 'Top' ), 'icon' => 'dashicons dashicons-arrow-up-alt' ), |
||
357 | 'right top' => array( 'label' => __( 'Top Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ), |
||
358 | ), |
||
359 | array( |
||
360 | 'left center' => array( 'label' => __( 'Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ), |
||
361 | 'center center' => array( 'label' => __( 'Center' ), 'icon' => 'background-position-center-icon' ), |
||
362 | 'right center' => array( 'label' => __( 'Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ), |
||
363 | ), |
||
364 | array( |
||
365 | 'left bottom' => array( 'label' => __( 'Bottom Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt' ), |
||
366 | 'center bottom' => array( 'label' => __( 'Bottom' ), 'icon' => 'dashicons dashicons-arrow-down-alt' ), |
||
367 | 'right bottom' => array( 'label' => __( 'Bottom Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt' ), |
||
368 | ), |
||
369 | ); |
||
370 | ?> |
||
371 | <tr> |
||
372 | <th scope="row"><?php _e( 'Image Position' ); ?></th> |
||
373 | <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Image Position' ); ?></span></legend> |
||
374 | <div class="background-position-control"> |
||
375 | View Code Duplication | <?php foreach ( $background_position_options as $group ) : ?> |
|
376 | <div class="button-group"> |
||
377 | <?php foreach ( $group as $value => $input ) : ?> |
||
378 | <label> |
||
379 | <input class="screen-reader-text" name="background-position" type="radio" value="<?php echo esc_attr( $value ); ?>"<?php checked( $value, $background_position ); ?>> |
||
380 | <span class="button display-options position"><span class="<?php echo esc_attr( $input['icon'] ); ?>" aria-hidden="true"></span></span> |
||
381 | <span class="screen-reader-text"><?php echo $input['label']; ?></span> |
||
382 | </label> |
||
383 | <?php endforeach; ?> |
||
384 | </div> |
||
385 | <?php endforeach; ?> |
||
386 | </div> |
||
387 | </fieldset></td> |
||
388 | </tr> |
||
389 | |||
390 | <tr> |
||
391 | <th scope="row"><label for="background-size"><?php _e( 'Image Size' ); ?></label></th> |
||
392 | <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Image Size' ); ?></span></legend> |
||
393 | <select id="background-size" name="background-size"> |
||
394 | <option value="auto"<?php selected( 'auto', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _ex( 'Original', 'Original Size' ); ?></option> |
||
395 | <option value="contain"<?php selected( 'contain', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _e( 'Fit to Screen' ); ?></option> |
||
396 | <option value="cover"<?php selected( 'cover', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _e( 'Fill Screen' ); ?></option> |
||
397 | </select> |
||
398 | </fieldset></td> |
||
399 | </tr> |
||
400 | |||
401 | <tr> |
||
402 | <th scope="row"><?php _ex( 'Repeat', 'Background Repeat' ); ?></th> |
||
403 | <td><fieldset><legend class="screen-reader-text"><span><?php _ex( 'Repeat', 'Background Repeat' ); ?></span></legend> |
||
404 | <input name="background-repeat" type="hidden" value="no-repeat"> |
||
405 | <label><input type="checkbox" name="background-repeat" value="repeat"<?php checked( 'repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?>> <?php _e( 'Repeat Background Image' ); ?></label> |
||
406 | </fieldset></td> |
||
407 | </tr> |
||
408 | |||
409 | <tr> |
||
410 | <th scope="row"><?php _ex( 'Scroll', 'Background Scroll' ); ?></th> |
||
411 | <td><fieldset><legend class="screen-reader-text"><span><?php _ex( 'Scroll', 'Background Scroll' ); ?></span></legend> |
||
412 | <input name="background-attachment" type="hidden" value="fixed"> |
||
413 | <label><input name="background-attachment" type="checkbox" value="scroll" <?php checked( 'scroll', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?>> <?php _e( 'Scroll with Page' ); ?></label> |
||
414 | </fieldset></td> |
||
415 | </tr> |
||
416 | <?php endif; // get_background_image() ?> |
||
417 | <tr> |
||
418 | <th scope="row"><?php _e( 'Background Color' ); ?></th> |
||
419 | <td><fieldset><legend class="screen-reader-text"><span><?php _e( 'Background Color' ); ?></span></legend> |
||
420 | <?php |
||
421 | $default_color = ''; |
||
422 | if ( current_theme_supports( 'custom-background', 'default-color' ) ) |
||
423 | $default_color = ' data-default-color="#' . esc_attr( get_theme_support( 'custom-background', 'default-color' ) ) . '"'; |
||
424 | ?> |
||
425 | <input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php echo $default_color ?>> |
||
426 | </fieldset></td> |
||
427 | </tr> |
||
428 | </tbody> |
||
429 | </table> |
||
430 | |||
431 | <?php wp_nonce_field('custom-background'); ?> |
||
432 | <?php submit_button( null, 'primary', 'save-background-options' ); ?> |
||
433 | </form> |
||
434 | |||
435 | </div> |
||
436 | <?php |
||
437 | } |
||
438 | |||
439 | /** |
||
440 | * Handle an Image upload for the background image. |
||
441 | * |
||
442 | * @since 3.0.0 |
||
443 | */ |
||
444 | public function handle_upload() { |
||
491 | |||
492 | /** |
||
493 | * Ajax handler for adding custom background context to an attachment. |
||
494 | * |
||
495 | * Triggered when the user adds a new background image from the |
||
496 | * Media Manager. |
||
497 | * |
||
498 | * @since 4.1.0 |
||
499 | */ |
||
500 | public function ajax_background_add() { |
||
516 | |||
517 | /** |
||
518 | * |
||
519 | * @since 3.4.0 |
||
520 | * @deprecated 3.5.0 |
||
521 | * |
||
522 | * @param array $form_fields |
||
523 | * @return array $form_fields |
||
524 | */ |
||
525 | public function attachment_fields_to_edit( $form_fields ) { |
||
528 | |||
529 | /** |
||
530 | * |
||
531 | * @since 3.4.0 |
||
532 | * @deprecated 3.5.0 |
||
533 | * |
||
534 | * @param array $tabs |
||
535 | * @return array $tabs |
||
536 | */ |
||
537 | public function filter_upload_tabs( $tabs ) { |
||
540 | |||
541 | /** |
||
542 | * |
||
543 | * @since 3.4.0 |
||
544 | * @deprecated 3.5.0 |
||
545 | */ |
||
546 | public function wp_set_background_image() { |
||
562 | } |
||
563 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: