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 Featured_Content 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 Featured_Content, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 26 | class Featured_Content { |
||
| 27 | |||
| 28 | /** |
||
| 29 | * The maximum number of posts that a Featured Content area can contain. We |
||
| 30 | * define a default value here but themes can override this by defining a |
||
| 31 | * "max_posts" entry in the second parameter passed in the call to |
||
| 32 | * add_theme_support( 'featured-content' ). |
||
| 33 | * |
||
| 34 | * @see Featured_Content::init() |
||
| 35 | */ |
||
| 36 | public static $max_posts = 15; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * The registered post types supported by Featured Content. Themes can add |
||
| 40 | * Featured Content support for registered post types by defining a |
||
| 41 | * 'post_types' argument (string|array) in the call to |
||
| 42 | * add_theme_support( 'featured-content' ). |
||
| 43 | * |
||
| 44 | * @see Featured_Content::init() |
||
| 45 | */ |
||
| 46 | public static $post_types = array( 'post' ); |
||
| 47 | |||
| 48 | /** |
||
| 49 | * The tag that is used to mark featured content. Users can define |
||
| 50 | * a custom tag name that will be stored in this variable. |
||
| 51 | * |
||
| 52 | * @see Featured_Content::hide_featured_term |
||
| 53 | */ |
||
| 54 | public static $tag; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * Instantiate. |
||
| 58 | * |
||
| 59 | * All custom functionality will be hooked into the "init" action. |
||
| 60 | */ |
||
| 61 | public static function setup() { |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Conditionally hook into WordPress. |
||
| 67 | * |
||
| 68 | * Themes must declare that they support this module by adding |
||
| 69 | * add_theme_support( 'featured-content' ); during after_setup_theme. |
||
| 70 | * |
||
| 71 | * If no theme support is found there is no need to hook into WordPress. We'll |
||
| 72 | * just return early instead. |
||
| 73 | * |
||
| 74 | * @uses Featured_Content::$max_posts |
||
| 75 | */ |
||
| 76 | public static function init() { |
||
| 137 | |||
| 138 | /** |
||
| 139 | * Hide "featured" tag from the front-end. |
||
| 140 | * |
||
| 141 | * Has to run on wp_loaded so that the preview filters of the customizer |
||
| 142 | * have a chance to alter the value. |
||
| 143 | */ |
||
| 144 | public static function wp_loaded() { |
||
| 155 | |||
| 156 | /** |
||
| 157 | * Get featured posts |
||
| 158 | * |
||
| 159 | * This method is not intended to be called directly. Theme developers should |
||
| 160 | * place a filter directly in their theme and then pass its name as a value of |
||
| 161 | * the "filter" key in the array passed as the $args parameter during the call |
||
| 162 | * to: add_theme_support( 'featured-content', $args ). |
||
| 163 | * |
||
| 164 | * @uses Featured_Content::get_featured_post_ids() |
||
| 165 | * |
||
| 166 | * @return array |
||
| 167 | */ |
||
| 168 | public static function get_featured_posts() { |
||
| 187 | |||
| 188 | /** |
||
| 189 | * Get featured post IDs |
||
| 190 | * |
||
| 191 | * This function will return the an array containing the post IDs of all |
||
| 192 | * featured posts. |
||
| 193 | * |
||
| 194 | * Sets the "featured_content_ids" transient. |
||
| 195 | * |
||
| 196 | * @return array Array of post IDs. |
||
| 197 | */ |
||
| 198 | public static function get_featured_post_ids() { |
||
| 265 | |||
| 266 | /** |
||
| 267 | * Delete Transient. |
||
| 268 | * |
||
| 269 | * Hooks in the "save_post" action. |
||
| 270 | * |
||
| 271 | * @see Featured_Content::validate_settings(). |
||
| 272 | */ |
||
| 273 | public static function delete_transient() { |
||
| 276 | |||
| 277 | /** |
||
| 278 | * Flush the Post Tag relationships cache. |
||
| 279 | * |
||
| 280 | * Hooks in the "update_option_featured-content" action. |
||
| 281 | */ |
||
| 282 | public static function flush_post_tag_cache( $prev, $opts ) { |
||
| 295 | |||
| 296 | /** |
||
| 297 | * Exclude featured posts from the blog query when the blog is the front-page, |
||
| 298 | * and user has not checked the "Also display tagged posts outside the Featured Content area" checkbox. |
||
| 299 | * |
||
| 300 | * Filter the home page posts, and remove any featured post ID's from it. |
||
| 301 | * Hooked onto the 'pre_get_posts' action, this changes the parameters of the |
||
| 302 | * query before it gets any posts. |
||
| 303 | * |
||
| 304 | * @uses Featured_Content::get_featured_post_ids(); |
||
| 305 | * @uses Featured_Content::get_setting(); |
||
| 306 | * @param WP_Query $query |
||
| 307 | * @return WP_Query Possibly modified WP_Query |
||
| 308 | */ |
||
| 309 | public static function pre_get_posts( $query ) { |
||
| 345 | |||
| 346 | /** |
||
| 347 | * Reset tag option when the saved tag is deleted. |
||
| 348 | * |
||
| 349 | * It's important to mention that the transient needs to be deleted, too. |
||
| 350 | * While it may not be obvious by looking at the function alone, the transient |
||
| 351 | * is deleted by Featured_Content::validate_settings(). |
||
| 352 | * |
||
| 353 | * Hooks in the "delete_post_tag" action. |
||
| 354 | * |
||
| 355 | * @see Featured_Content::validate_settings(). |
||
| 356 | * |
||
| 357 | * @param int $tag_id The term_id of the tag that has been deleted. |
||
| 358 | * @return void |
||
| 359 | */ |
||
| 360 | public static function delete_post_tag( $tag_id ) { |
||
| 371 | |||
| 372 | /** |
||
| 373 | * Hide featured tag from displaying when global terms are queried from |
||
| 374 | * the front-end. |
||
| 375 | * |
||
| 376 | * Hooks into the "get_terms" filter. |
||
| 377 | * |
||
| 378 | * @uses Featured_Content::get_setting() |
||
| 379 | * |
||
| 380 | * @param array $terms A list of term objects. This is the return value of get_terms(). |
||
| 381 | * @param array $taxonomies An array of taxonomy slugs. |
||
| 382 | * @return array $terms |
||
| 383 | */ |
||
| 384 | public static function hide_featured_term( $terms, $taxonomies, $args ) { |
||
| 385 | |||
| 386 | // This filter is only appropriate on the front-end. |
||
| 387 | View Code Duplication | if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ) { |
|
| 388 | return $terms; |
||
| 389 | } |
||
| 390 | |||
| 391 | // We only want to hide the featured tag. |
||
| 392 | if ( ! in_array( 'post_tag', $taxonomies ) ) { |
||
| 393 | return $terms; |
||
| 394 | } |
||
| 395 | |||
| 396 | // Bail if no terms were returned. |
||
| 397 | if ( empty( $terms ) ) { |
||
| 398 | return $terms; |
||
| 399 | } |
||
| 400 | |||
| 401 | // Bail if term objects are unavailable. |
||
| 402 | if ( 'all' != $args['fields'] ) { |
||
| 403 | return $terms; |
||
| 404 | } |
||
| 405 | |||
| 406 | $settings = self::get_setting(); |
||
| 407 | |||
| 408 | View Code Duplication | if ( false !== self::$tag ) { |
|
| 409 | foreach ( $terms as $order => $term ) { |
||
| 410 | if ( |
||
| 411 | is_object( $term ) |
||
| 412 | && ( |
||
| 413 | $settings['tag-id'] === $term->term_id |
||
| 414 | || $settings['tag-name'] === $term->name |
||
| 415 | ) |
||
| 416 | ) { |
||
| 417 | unset( $terms[ $order ] ); |
||
| 418 | } |
||
| 419 | } |
||
| 420 | } |
||
| 421 | |||
| 422 | return $terms; |
||
| 423 | } |
||
| 424 | |||
| 425 | /** |
||
| 426 | * Hide featured tag from displaying when terms associated with a post object |
||
| 427 | * are queried from the front-end. |
||
| 428 | * |
||
| 429 | * Hooks into the "get_the_terms" filter. |
||
| 430 | * |
||
| 431 | * @uses Featured_Content::get_setting() |
||
| 432 | * |
||
| 433 | * @param array $terms A list of term objects. This is the return value of get_the_terms(). |
||
| 434 | * @param int $id The ID field for the post object that terms are associated with. |
||
| 435 | * @param array $taxonomy An array of taxonomy slugs. |
||
| 436 | * @return array $terms |
||
| 437 | */ |
||
| 438 | public static function hide_the_featured_term( $terms, $id, $taxonomy ) { |
||
| 439 | |||
| 440 | // This filter is only appropriate on the front-end. |
||
| 441 | View Code Duplication | if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) ) { |
|
| 442 | return $terms; |
||
| 443 | } |
||
| 444 | |||
| 445 | // Make sure we are in the correct taxonomy. |
||
| 446 | if ( 'post_tag' != $taxonomy ) { |
||
| 447 | return $terms; |
||
| 448 | } |
||
| 449 | |||
| 450 | // No terms? Return early! |
||
| 451 | if ( empty( $terms ) ) { |
||
| 452 | return $terms; |
||
| 453 | } |
||
| 454 | |||
| 455 | $settings = self::get_setting(); |
||
| 456 | $tag = get_term_by( 'name', $settings['tag-name'], 'post_tag' ); |
||
| 457 | |||
| 458 | View Code Duplication | if ( false !== $tag ) { |
|
| 459 | foreach ( $terms as $order => $term ) { |
||
| 460 | if ( $settings['tag-id'] === $term->term_id || $settings['tag-name'] === $term->name ) { |
||
| 461 | unset( $terms[ $order ] ); |
||
| 462 | } |
||
| 463 | } |
||
| 464 | } |
||
| 465 | |||
| 466 | return $terms; |
||
| 467 | } |
||
| 468 | |||
| 469 | /** |
||
| 470 | * Register custom setting on the Settings -> Reading screen. |
||
| 471 | * |
||
| 472 | * @uses Featured_Content::render_form() |
||
| 473 | * @uses Featured_Content::validate_settings() |
||
| 474 | * |
||
| 475 | * @return void |
||
| 476 | */ |
||
| 477 | public static function register_setting() { |
||
| 483 | |||
| 484 | /** |
||
| 485 | * Add settings to the Customizer. |
||
| 486 | * |
||
| 487 | * @param WP_Customize_Manager $wp_customize Theme Customizer object. |
||
| 488 | */ |
||
| 489 | public static function customize_register( $wp_customize ) { |
||
| 561 | |||
| 562 | /** |
||
| 563 | * Enqueue the tag suggestion script. |
||
| 564 | */ |
||
| 565 | public static function enqueue_scripts() { |
||
| 568 | |||
| 569 | /** |
||
| 570 | * Renders all form fields on the Settings -> Reading screen. |
||
| 571 | */ |
||
| 572 | public static function render_form() { |
||
| 575 | |||
| 576 | /** |
||
| 577 | * Get settings |
||
| 578 | * |
||
| 579 | * Get all settings recognized by this module. This function will return all |
||
| 580 | * settings whether or not they have been stored in the database yet. This |
||
| 581 | * ensures that all keys are available at all times. |
||
| 582 | * |
||
| 583 | * In the event that you only require one setting, you may pass its name as the |
||
| 584 | * first parameter to the function and only that value will be returned. |
||
| 585 | * |
||
| 586 | * @param string $key The key of a recognized setting. |
||
| 587 | * @return mixed Array of all settings by default. A single value if passed as first parameter. |
||
| 588 | */ |
||
| 589 | public static function get_setting( $key = 'all' ) { |
||
| 627 | |||
| 628 | /** |
||
| 629 | * Validate settings |
||
| 630 | * |
||
| 631 | * Make sure that all user supplied content is in an expected format before |
||
| 632 | * saving to the database. This function will also delete the transient set in |
||
| 633 | * Featured_Content::get_featured_content(). |
||
| 634 | * |
||
| 635 | * @uses Featured_Content::delete_transient() |
||
| 636 | * |
||
| 637 | * @param array $input |
||
| 638 | * @return array $output |
||
| 639 | */ |
||
| 640 | public static function validate_settings( $input ) { |
||
| 669 | |||
| 670 | /** |
||
| 671 | * Removes the quantity setting from the options array. |
||
| 672 | * |
||
| 673 | * @return void |
||
| 674 | */ |
||
| 675 | public static function switch_theme() { |
||
| 683 | |||
| 684 | public static function jetpack_update_featured_content_for_split_terms( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { |
||
| 694 | } |
||
| 695 | |||
| 696 | /** |
||
| 723 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.