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_Calypsoify 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_Calypsoify, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 6 | class Jetpack_Calypsoify { |
||
| 7 | |||
| 8 | /** |
||
| 9 | * Singleton instance of `Jetpack_Calypsoify`. |
||
| 10 | * |
||
| 11 | * @var object |
||
| 12 | */ |
||
| 13 | public static $instance = false; |
||
| 14 | |||
| 15 | /** |
||
| 16 | * Is Calypsoify enabled, based on any value of `calypsoify` user meta. |
||
| 17 | * |
||
| 18 | * @var bool |
||
| 19 | */ |
||
| 20 | public $is_calypsoify_enabled = false; |
||
| 21 | |||
| 22 | private function __construct() { |
||
| 23 | add_action( 'wp_loaded', array( $this, 'setup' ) ); |
||
| 24 | } |
||
| 25 | |||
| 26 | public static function getInstance() { |
||
| 27 | if ( ! self::$instance ) { |
||
| 28 | self::$instance = new self(); |
||
| 29 | } |
||
| 30 | |||
| 31 | return self::$instance; |
||
| 32 | } |
||
| 33 | |||
| 34 | public function setup() { |
||
| 35 | $this->is_calypsoify_enabled = 1 == (int) get_user_meta( get_current_user_id(), 'calypsoify', true ); |
||
| 36 | add_action( 'admin_init', array( $this, 'check_param' ), 4 ); |
||
| 37 | |||
| 38 | if ( $this->is_calypsoify_enabled ) { |
||
| 39 | add_action( 'admin_init', array( $this, 'setup_admin' ), 6 ); |
||
| 40 | } |
||
| 41 | |||
| 42 | // Make this always available -- in case calypsoify gets toggled off. |
||
| 43 | add_action( 'wp_ajax_jetpack_toggle_autoupdate', array( $this, 'jetpack_toggle_autoupdate' ) ); |
||
| 44 | add_filter( 'handle_bulk_actions-plugins', array( $this, 'handle_bulk_actions_plugins' ), 10, 3 ); |
||
| 45 | } |
||
| 46 | |||
| 47 | public function setup_admin() { |
||
| 48 | if ( $this->is_page_gutenberg() ) { |
||
| 49 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_for_gutenberg' ), 100 ); |
||
| 50 | return; |
||
| 51 | } |
||
| 52 | |||
| 53 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 100 ); |
||
| 54 | |||
| 55 | add_action( 'manage_plugins_columns', array( $this, 'manage_plugins_columns_header' ) ); |
||
| 56 | add_action( 'manage_plugins_custom_column', array( $this, 'manage_plugins_custom_column' ), 10, 2 ); |
||
| 57 | add_filter( 'bulk_actions-plugins', array( $this, 'bulk_actions_plugins' ) ); |
||
| 58 | |||
| 59 | add_action( 'current_screen', array( $this, 'attach_views_filter' ) ); |
||
| 60 | |||
| 61 | if ( 'plugins.php' === basename( $_SERVER['PHP_SELF'] ) ) { |
||
| 62 | add_action( 'admin_notices', array( $this, 'plugins_admin_notices' ) ); |
||
| 63 | } |
||
| 64 | } |
||
| 65 | |||
| 66 | public function manage_plugins_columns_header( $columns ) { |
||
| 72 | |||
| 73 | public function manage_plugins_custom_column( $column_name, $slug ) { |
||
| 113 | |||
| 114 | public static function get_dotorg_repo_plugins() { |
||
| 118 | |||
| 119 | public function bulk_actions_plugins( $bulk_actions ) { |
||
| 124 | |||
| 125 | public function handle_bulk_actions_plugins( $redirect_to, $action, $slugs ) { |
||
| 142 | |||
| 143 | public function plugins_admin_notices() { |
||
| 152 | |||
| 153 | public function jetpack_toggle_autoupdate() { |
||
| 184 | |||
| 185 | View Code Duplication | public function enqueue() { |
|
| 186 | wp_enqueue_script( 'calypsoify_wpadminmods_js', plugin_dir_url( __FILE__ ) . 'mods.js', false, JETPACK__VERSION ); |
||
| 187 | wp_localize_script( 'calypsoify_wpadminmods_js', 'CalypsoifyOpts', array( |
||
| 188 | 'nonces' => array( |
||
| 189 | 'autoupdate_plugins' => wp_create_nonce( 'jetpack_toggle_autoupdate-plugins' ), |
||
| 190 | 'autoupdate_plugins_translations' => wp_create_nonce( 'jetpack_toggle_autoupdate-plugins_translations' ), |
||
| 191 | ) |
||
| 192 | ) ); |
||
| 193 | } |
||
| 194 | |||
| 195 | public function enqueue_for_gutenberg() { |
||
| 196 | wp_enqueue_script( 'calypsoify_wpadminmods_js', plugin_dir_url( __FILE__ ) . 'mods-gutenberg.js', false, JETPACK__VERSION ); |
||
| 197 | wp_localize_script( |
||
| 198 | 'calypsoify_wpadminmods_js', |
||
| 199 | 'calypsoifyGutenberg', |
||
| 200 | array( |
||
| 201 | 'closeUrl' => $this->get_close_gutenberg_url(), |
||
| 202 | 'manageReusableBlocksUrl' => $this->get_calypso_origin() . '/types/wp_block' . $this->get_site_suffix(), |
||
| 203 | ) |
||
| 204 | ); |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Returns the Calypso domain that originated the current request. |
||
| 209 | * |
||
| 210 | * @return string |
||
| 211 | */ |
||
| 212 | private function get_calypso_origin() { |
||
| 213 | $origin = ! empty( $_GET['origin'] ) ? $_GET['origin'] : 'https://wordpress.com'; |
||
| 214 | $whitelist = array( |
||
| 215 | 'http://calypso.localhost:3000', |
||
| 216 | 'http://127.0.0.1:41050', // Desktop App |
||
| 217 | 'https://wpcalypso.wordpress.com', |
||
| 218 | 'https://horizon.wordpress.com', |
||
| 219 | 'https://wordpress.com', |
||
| 220 | ); |
||
| 221 | return in_array( $origin, $whitelist ) ? $origin : 'https://wordpress.com'; |
||
| 222 | |||
| 223 | View Code Duplication | function get_site_suffix() { |
|
| 235 | } |
||
| 236 | |||
| 237 | /** |
||
| 238 | * Returns the site slug suffix to be used as part of the Calypso URLs. It already |
||
| 239 | * includes the slash separator at the beginning. |
||
| 240 | * |
||
| 241 | * @example "https://wordpress.com/block-editor" . $this->get_site_suffix() |
||
| 242 | * |
||
| 243 | * @return string |
||
| 244 | */ |
||
| 245 | View Code Duplication | private function get_site_suffix() { |
|
| 257 | |||
| 258 | /** |
||
| 259 | * Returns the Calypso URL that displays either the current post type list (if no args |
||
| 260 | * are supplied) or the classic editor for the current post (if a post ID is supplied). |
||
| 261 | * |
||
| 262 | * @param int|null $post_id |
||
| 263 | * @return string |
||
| 264 | */ |
||
| 265 | public function get_calypso_url( $post_id = null ) { |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Returns the URL to be used on the block editor close button for going back to the |
||
| 286 | * Calypso post list. |
||
| 287 | * |
||
| 288 | * @return string |
||
| 289 | */ |
||
| 290 | public function get_close_gutenberg_url() { |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Returns the URL for switching the user's editor to the Calypso (WordPress.com Classic) editor. |
||
| 296 | * |
||
| 297 | * @return string |
||
| 298 | */ |
||
| 299 | public function get_switch_to_classic_editor_url() { |
||
| 306 | |||
| 307 | public function check_param() { |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Return whether a post type should display the Gutenberg/block editor. |
||
| 323 | * |
||
| 324 | * @since 6.7.0 |
||
| 325 | */ |
||
| 326 | public function is_post_type_gutenberg( $post_type ) { |
||
| 329 | |||
| 330 | public function is_page_gutenberg() { |
||
| 358 | |||
| 359 | /** |
||
| 360 | * Attach a WP_List_Table views filter to all screens. |
||
| 361 | */ |
||
| 362 | public function attach_views_filter( $current_screen ) { |
||
| 365 | |||
| 366 | /** |
||
| 367 | * Remove the parentheses from list table view counts when Calypsofied. |
||
| 368 | * |
||
| 369 | * @param array $views Array of views. See: WP_List_Table::get_views(). |
||
| 370 | * @return array Filtered views. |
||
| 371 | */ |
||
| 372 | public function filter_views( $views ) { |
||
| 379 | } |
||
| 380 | |||
| 382 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return,dieorexitstatements that have been added for debug purposes.In the above example, the last
return falsewill never be executed, because a return statement has already been met in every possible execution path.