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 Jetpack_Comments 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 Jetpack_Comments, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 12 | class Jetpack_Comments extends Highlander_Comments_Base { |
||
| 13 | |||
| 14 | /** Variables *************************************************************/ |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Possible comment form sources |
||
| 18 | * @var array |
||
| 19 | */ |
||
| 20 | public $id_sources = array(); |
||
| 21 | |||
| 22 | /** |
||
| 23 | * URL |
||
| 24 | * @var string |
||
| 25 | */ |
||
| 26 | public $signed_url = ''; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * The default comment form color scheme |
||
| 30 | * @var string |
||
| 31 | * @see ::set_default_color_theme_based_on_theme_settings() |
||
| 32 | */ |
||
| 33 | public $default_color_scheme = 'light'; |
||
| 34 | |||
| 35 | /** Methods ***************************************************************/ |
||
| 36 | |||
| 37 | public static function init() { |
||
| 38 | static $instance = false; |
||
| 39 | |||
| 40 | if ( !$instance ) { |
||
| 41 | $instance = new Jetpack_Comments; |
||
| 42 | } |
||
| 43 | |||
| 44 | return $instance; |
||
| 45 | } |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Main constructor for Comments |
||
| 49 | * |
||
| 50 | * @since JetpackComments (1.4) |
||
| 51 | */ |
||
| 52 | public function __construct() { |
||
| 53 | parent::__construct(); |
||
| 54 | |||
| 55 | // Comments is loaded |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Fires after the Jetpack_Comments object has been instantiated |
||
| 59 | * |
||
| 60 | * @module comments |
||
| 61 | * |
||
| 62 | * @since 1.4.0 |
||
| 63 | * |
||
| 64 | * @param array $jetpack_comments_loaded First element in array of type Jetpack_Comments |
||
| 65 | **/ |
||
| 66 | do_action_ref_array( 'jetpack_comments_loaded', array( $this ) ); |
||
| 67 | add_action( 'after_setup_theme', array( $this, 'set_default_color_theme_based_on_theme_settings' ), 100 ); |
||
| 68 | } |
||
| 69 | |||
| 70 | public function set_default_color_theme_based_on_theme_settings() { |
||
| 71 | if ( function_exists( 'twentyeleven_get_theme_options' ) ) { |
||
| 72 | $theme_options = twentyeleven_get_theme_options(); |
||
| 73 | $theme_color_scheme = isset( $theme_options['color_scheme'] ) ? $theme_options['color_scheme'] : 'transparent'; |
||
| 74 | } else { |
||
| 75 | $theme_color_scheme = get_theme_mod( 'color_scheme', 'transparent' ); |
||
| 76 | } |
||
| 77 | // Default for $theme_color_scheme is 'transparent' just so it doesn't match 'light' or 'dark' |
||
| 78 | // The default for Jetpack's color scheme is still defined above as 'light' |
||
| 79 | |||
| 80 | if ( false !== stripos( $theme_color_scheme, 'light' ) ) { |
||
| 81 | $this->default_color_scheme = 'light'; |
||
| 82 | } elseif ( false !== stripos( $theme_color_scheme, 'dark' ) ) { |
||
| 83 | $this->default_color_scheme = 'dark'; |
||
| 84 | } |
||
| 85 | } |
||
| 86 | |||
| 87 | /** Private Methods *******************************************************/ |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Set any global variables or class variables |
||
| 91 | * @since JetpackComments (1.4) |
||
| 92 | */ |
||
| 93 | protected function setup_globals() { |
||
| 94 | parent::setup_globals(); |
||
| 95 | |||
| 96 | // Sources |
||
| 97 | $this->id_sources = array( |
||
| 98 | 'guest', |
||
| 99 | 'jetpack', |
||
| 100 | 'wordpress', |
||
| 101 | 'twitter', |
||
| 102 | 'facebook' |
||
| 103 | ); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Setup actions for methods in this class |
||
| 108 | * @since JetpackComments (1.4) |
||
| 109 | */ |
||
| 110 | protected function setup_actions() { |
||
| 111 | parent::setup_actions(); |
||
| 112 | |||
| 113 | // Selfishly remove everything from the existing comment form |
||
| 114 | remove_all_actions( 'comment_form_before' ); |
||
| 115 | remove_all_actions( 'comment_form_after' ); |
||
| 116 | |||
| 117 | // Selfishly add only our actions back to the comment form |
||
| 118 | add_action( 'comment_form_before', array( $this, 'comment_form_before' ) ); |
||
| 119 | add_action( 'comment_form_after', array( $this, 'comment_form_after' ) ); |
||
| 120 | |||
| 121 | // Before a comment is posted |
||
| 122 | add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ), 1 ); |
||
| 123 | |||
| 124 | // After a comment is posted |
||
| 125 | add_action( 'comment_post', array( $this, 'add_comment_meta' ) ); |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Setup filters for methods in this class |
||
| 130 | * @since 1.6.2 |
||
| 131 | */ |
||
| 132 | protected function setup_filters() { |
||
| 133 | parent::setup_filters(); |
||
| 134 | |||
| 135 | add_filter( 'comment_post_redirect', array( $this, 'capture_comment_post_redirect_to_reload_parent_frame' ), 100 ); |
||
| 136 | add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 4 ); |
||
| 137 | } |
||
| 138 | |||
| 139 | /** |
||
| 140 | * Get the comment avatar from Gravatar, Twitter, or Facebook |
||
| 141 | * |
||
| 142 | * @since JetpackComments (1.4) |
||
| 143 | * @param string $avatar Current avatar URL |
||
| 144 | * @param string $comment Comment for the avatar |
||
| 145 | * @param int $size Size of the avatar |
||
| 146 | * @param string $default Not used |
||
| 147 | * @return string New avatar |
||
| 148 | */ |
||
| 149 | public function get_avatar( $avatar, $comment, $size, $default ) { |
||
|
|
|||
| 150 | if ( ! isset( $comment->comment_post_ID ) || ! isset( $comment->comment_ID ) ) { |
||
| 151 | // it's not a comment - bail |
||
| 152 | return $avatar; |
||
| 153 | } |
||
| 154 | |||
| 155 | if ( false === strpos( $comment->comment_author_url, '/www.facebook.com/' ) && false === strpos( $comment->comment_author_url, '/twitter.com/' ) ) { |
||
| 156 | // It's neither FB nor Twitter - bail |
||
| 157 | return $avatar; |
||
| 158 | } |
||
| 159 | |||
| 160 | // It's a FB or Twitter avatar |
||
| 161 | $foreign_avatar = get_comment_meta( $comment->comment_ID, 'hc_avatar', true ); |
||
| 162 | if ( empty( $foreign_avatar ) ) { |
||
| 163 | // Can't find the avatar details - bail |
||
| 164 | return $avatar; |
||
| 165 | } |
||
| 166 | |||
| 167 | // Return the FB or Twitter avatar |
||
| 168 | return preg_replace( '#src=([\'"])[^\'"]+\\1#', 'src=\\1' . esc_url( $this->photon_avatar( $foreign_avatar, $size ) ) . '\\1', $avatar ); |
||
| 169 | } |
||
| 170 | |||
| 171 | /** Output Methods ********************************************************/ |
||
| 172 | |||
| 173 | /** |
||
| 174 | * Start capturing the core comment_form() output |
||
| 175 | * @since JetpackComments (1.4) |
||
| 176 | */ |
||
| 177 | public function comment_form_before() { |
||
| 178 | /** |
||
| 179 | * Filters the setting that determines if Jetpagk comments should be enabled for |
||
| 180 | * the current post type. |
||
| 181 | * |
||
| 182 | * @module comments |
||
| 183 | * |
||
| 184 | * @since 3.8.1 |
||
| 185 | * |
||
| 186 | * @param boolean $return Should comments be enabled? |
||
| 187 | */ |
||
| 188 | if ( ! apply_filters( 'jetpack_comment_form_enabled_for_' . get_post_type(), true ) ) { |
||
| 189 | return; |
||
| 190 | } |
||
| 191 | |||
| 192 | // Add some JS to the footer |
||
| 193 | add_action( 'wp_footer', array( $this, 'watch_comment_parent' ), 100 ); |
||
| 194 | |||
| 195 | ob_start(); |
||
| 196 | } |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Noop the default comment form output, get some options, and output our |
||
| 200 | * tricked out totally radical comment form. |
||
| 201 | * |
||
| 202 | * @since JetpackComments (1.4) |
||
| 203 | */ |
||
| 204 | public function comment_form_after() { |
||
| 309 | |||
| 310 | /** |
||
| 311 | * Add some JS to wp_footer to watch for hierarchical reply parent change |
||
| 312 | * |
||
| 313 | * @since JetpackComments (1.4) |
||
| 314 | */ |
||
| 315 | public function watch_comment_parent() { |
||
| 316 | $url_origin = set_url_scheme( 'http://jetpack.wordpress.com' ); |
||
| 317 | ?> |
||
| 407 | |||
| 408 | /** |
||
| 409 | * Verify the hash included in remote comments. |
||
| 410 | * |
||
| 411 | * @since JetpackComments (1.4) |
||
| 412 | * @param type $comment Not used |
||
| 413 | */ |
||
| 414 | public function pre_comment_on_post( $comment ) { |
||
| 443 | |||
| 444 | /** Capabilities **********************************************************/ |
||
| 445 | |||
| 446 | /** |
||
| 447 | * Add some additional comment meta after comment is saved about what |
||
| 448 | * service the comment is from, the avatar, user_id, etc... |
||
| 449 | * |
||
| 450 | * @since JetpackComments (1.4) |
||
| 451 | * @param type $comment_id |
||
| 452 | */ |
||
| 453 | public function add_comment_meta( $comment_id ) { |
||
| 573 | } |
||
| 574 | |||
| 576 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.