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 Admin_Menu 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 Admin_Menu, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Admin_Menu { |
||
17 | /** |
||
18 | * Holds class instances. |
||
19 | * |
||
20 | * @var array |
||
21 | */ |
||
22 | protected static $instances; |
||
23 | |||
24 | /** |
||
25 | * Whether the current request is a REST API request. |
||
26 | * |
||
27 | * @var bool |
||
28 | */ |
||
29 | protected $is_api_request = false; |
||
30 | |||
31 | /** |
||
32 | * Domain of the current site. |
||
33 | * |
||
34 | * @var string |
||
35 | */ |
||
36 | protected $domain; |
||
37 | |||
38 | /** |
||
39 | * Admin_Menu constructor. |
||
40 | */ |
||
41 | protected function __construct() { |
||
50 | |||
51 | /** |
||
52 | * Returns class instance. |
||
53 | * |
||
54 | * @return Admin_Menu |
||
55 | */ |
||
56 | public static function get_instance() { |
||
65 | |||
66 | /** |
||
67 | * Sets up class properties for REST API requests. |
||
68 | * |
||
69 | * @param WP_REST_Response $response Response from the endpoint. |
||
70 | */ |
||
71 | public function rest_api_init( $response ) { |
||
76 | |||
77 | /** |
||
78 | * Create the desired menu output. |
||
79 | */ |
||
80 | public function reregister_menu_items() { |
||
128 | |||
129 | /** |
||
130 | * Adds My Home menu. |
||
131 | */ |
||
132 | public function add_my_home_menu() { |
||
135 | |||
136 | /** |
||
137 | * Adds Stats menu. |
||
138 | */ |
||
139 | public function add_stats_menu() { |
||
142 | |||
143 | /** |
||
144 | * Adds Upgrades menu. |
||
145 | */ |
||
146 | public function add_upgrades_menu() { |
||
169 | |||
170 | /** |
||
171 | * Adds Posts menu. |
||
172 | * |
||
173 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
174 | */ |
||
175 | View Code Duplication | public function add_posts_menu( $wp_admin = false ) { |
|
186 | |||
187 | /** |
||
188 | * Adds Media menu. |
||
189 | * |
||
190 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
191 | */ |
||
192 | public function add_media_menu( $wp_admin = false ) { |
||
201 | |||
202 | /** |
||
203 | * Adds Page menu. |
||
204 | * |
||
205 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
206 | */ |
||
207 | View Code Duplication | public function add_page_menu( $wp_admin = false ) { |
|
218 | |||
219 | /** |
||
220 | * Adds Testimonials menu. |
||
221 | * |
||
222 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
223 | */ |
||
224 | public function add_testimonials_menu( $wp_admin = false ) { |
||
227 | |||
228 | /** |
||
229 | * Adds Portfolio menu. |
||
230 | * |
||
231 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
232 | */ |
||
233 | public function add_portfolio_menu( $wp_admin = false ) { |
||
236 | |||
237 | /** |
||
238 | * Adds a custom post type menu. |
||
239 | * |
||
240 | * @param string $post_type Custom post type. |
||
241 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
242 | */ |
||
243 | public function add_custom_post_type_menu( $post_type, $wp_admin = false ) { |
||
254 | |||
255 | /** |
||
256 | * Adds Comments menu. |
||
257 | * |
||
258 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
259 | */ |
||
260 | public function add_comments_menu( $wp_admin = false ) { |
||
267 | |||
268 | /** |
||
269 | * Adds Appearance menu. |
||
270 | * |
||
271 | * @param bool $wp_admin_themes Optional. Whether Themes link should point to Calypso or wp-admin. Default false (Calypso). |
||
272 | * @param bool $wp_admin_customize Optional. Whether Customize link should point to Calypso or wp-admin. Default false (Calypso). |
||
273 | * @return string The Customizer URL. |
||
274 | */ |
||
275 | public function add_appearance_menu( $wp_admin_themes = false, $wp_admin_customize = false ) { |
||
276 | $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; |
||
277 | $default_customize_slug = add_query_arg( 'return', rawurlencode( remove_query_arg( wp_removable_query_args(), $request_uri ) ), 'customize.php' ); |
||
278 | $default_customize_header_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $default_customize_slug ); |
||
279 | // TODO: Remove WPCom_Theme_Customizer::modify_header_menu_links() and WPcom_Custom_Header::modify_admin_menu_links(). |
||
280 | $default_customize_header_slug_2 = admin_url( 'themes.php?page=custom-header' ); |
||
281 | $default_customize_background_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'background_image' ) ), $default_customize_slug ); |
||
282 | // TODO: Remove Colors_Manager::modify_header_menu_links() and Colors_Manager_Common::modify_header_menu_links(). |
||
283 | $default_customize_background_slug_2 = add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), admin_url( 'customize.php' ) ); |
||
284 | |||
285 | if ( ! $wp_admin_customize ) { |
||
286 | $customize_url = 'https://wordpress.com/customize/' . $this->domain; |
||
287 | } elseif ( $this->is_api_request ) { |
||
288 | // In case this is an api request we will have to add the 'return' querystring via JS. |
||
289 | $customize_url = 'customize.php'; |
||
290 | } else { |
||
291 | $customize_url = $default_customize_slug; |
||
292 | } |
||
293 | |||
294 | $submenus_to_update = array( |
||
295 | $default_customize_slug => $customize_url, |
||
296 | $default_customize_header_slug_1 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ), |
||
297 | $default_customize_header_slug_2 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ), |
||
298 | $default_customize_background_slug_1 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ), |
||
299 | $default_customize_background_slug_2 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ), |
||
300 | ); |
||
301 | |||
302 | if ( ! $wp_admin_themes ) { |
||
303 | $submenus_to_update['themes.php'] = 'https://wordpress.com/themes/' . $this->domain; |
||
304 | } |
||
305 | |||
306 | if ( ! $wp_admin_customize ) { |
||
307 | $submenus_to_update['widgets.php'] = add_query_arg( array( 'autofocus' => array( 'panel' => 'widgets' ) ), $customize_url ); |
||
308 | $submenus_to_update['gutenberg-widgets'] = add_query_arg( array( 'autofocus' => array( 'panel' => 'widgets' ) ), $customize_url ); |
||
309 | $submenus_to_update['nav-menus.php'] = add_query_arg( array( 'autofocus' => array( 'panel' => 'nav_menus' ) ), $customize_url ); |
||
310 | } |
||
311 | |||
312 | $this->update_submenus( 'themes.php', $submenus_to_update ); |
||
313 | |||
314 | remove_submenu_page( 'themes.php', 'custom-header' ); |
||
315 | remove_submenu_page( 'themes.php', 'custom-background' ); |
||
316 | |||
317 | return $customize_url; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Adds Plugins menu. |
||
322 | * |
||
323 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
324 | */ |
||
325 | public function add_plugins_menu( $wp_admin = false ) { |
||
326 | if ( $wp_admin ) { |
||
327 | return; |
||
328 | } |
||
329 | |||
330 | remove_submenu_page( 'plugins.php', 'plugin-install.php' ); |
||
331 | remove_submenu_page( 'plugins.php', 'plugin-editor.php' ); |
||
332 | |||
333 | $this->update_menu( 'plugins.php', 'https://wordpress.com/plugins/' . $this->domain ); |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * Adds Users menu. |
||
338 | * |
||
339 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
340 | */ |
||
341 | public function add_users_menu( $wp_admin = false ) { |
||
342 | if ( current_user_can( 'list_users' ) ) { |
||
343 | if ( ! $wp_admin ) { |
||
344 | $submenus_to_update = array( |
||
345 | 'users.php' => 'https://wordpress.com/people/team/' . $this->domain, |
||
346 | 'user-new.php' => 'https://wordpress.com/people/new/' . $this->domain, |
||
347 | 'profile.php' => 'https://wordpress.com/me', |
||
348 | ); |
||
349 | $this->update_submenus( 'users.php', $submenus_to_update ); |
||
350 | } |
||
351 | |||
352 | add_submenu_page( 'users.php', esc_attr__( 'Account Settings', 'jetpack' ), __( 'Account Settings', 'jetpack' ), 'read', 'https://wordpress.com/me/account' ); |
||
353 | } else { |
||
354 | if ( ! $wp_admin ) { |
||
355 | $submenus_to_update = array( |
||
356 | 'user-new.php' => 'https://wordpress.com/people/new/' . $this->domain, |
||
357 | 'profile.php' => 'https://wordpress.com/me', |
||
358 | ); |
||
359 | $this->update_submenus( 'profile.php', $submenus_to_update ); |
||
360 | } |
||
361 | |||
362 | add_submenu_page( 'profile.php', esc_attr__( 'Account Settings', 'jetpack' ), __( 'Account Settings', 'jetpack' ), 'read', 'https://wordpress.com/me/account' ); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Adds Tools menu. |
||
368 | * |
||
369 | * @param bool $wp_admin_import Optional. Whether Import link should point to Calypso or wp-admin. Default false (Calypso). |
||
370 | * @param bool $wp_admin_export Optional. Whether Export link should point to Calypso or wp-admin. Default false (Calypso). |
||
371 | */ |
||
372 | public function add_tools_menu( $wp_admin_import = false, $wp_admin_export = false ) { |
||
388 | |||
389 | /** |
||
390 | * Adds Settings menu. |
||
391 | * |
||
392 | * @param bool $wp_admin Optional. Whether links should point to Calypso or wp-admin. Default false (Calypso). |
||
393 | */ |
||
394 | public function add_options_menu( $wp_admin = false ) { |
||
404 | |||
405 | /** |
||
406 | * Adds Jetpack menu. |
||
407 | */ |
||
408 | public function add_jetpack_menu() { |
||
439 | |||
440 | /** |
||
441 | * Updates the menu data of the given menu slug. |
||
442 | * |
||
443 | * @param string $slug Slug of the menu to update. |
||
444 | * @param string $url New menu URL. |
||
|
|||
445 | * @param string $title New menu title. |
||
446 | * @param string $cap New menu capability. |
||
447 | * @param string $icon New menu icon. |
||
448 | * @param int $position New menu position. |
||
449 | * @return bool Whether the menu has been updated. |
||
450 | */ |
||
451 | public function update_menu( $slug, $url = null, $title = null, $cap = null, $icon = null, $position = null ) { |
||
506 | |||
507 | /** |
||
508 | * Updates the submenus of the given menu slug. |
||
509 | * |
||
510 | * @param string $slug Menu slug. |
||
511 | * @param array $submenus_to_update Array of new submenu slugs. |
||
512 | */ |
||
513 | public function update_submenus( $slug, $submenus_to_update ) { |
||
528 | |||
529 | /** |
||
530 | * Remove submenu items from given menu slug. |
||
531 | * |
||
532 | * @param string $slug Menu slug. |
||
533 | */ |
||
534 | public function remove_submenus( $slug ) { |
||
542 | |||
543 | /** |
||
544 | * Adds a menu separator. |
||
545 | * |
||
546 | * @param int $position The position in the menu order this item should appear. |
||
547 | * @param string $cap Optional. The capability required for this menu to be displayed to the user. |
||
548 | * Default: 'read'. |
||
549 | */ |
||
550 | public function add_admin_menu_separator( $position, $cap = 'read' ) { |
||
563 | |||
564 | /** |
||
565 | * Enqueues scripts and styles. |
||
566 | */ |
||
567 | public function enqueue_scripts() { |
||
589 | |||
590 | /** |
||
591 | * Dequeues unnecessary scripts. |
||
592 | */ |
||
593 | public function dequeue_scripts() { |
||
596 | |||
597 | /** |
||
598 | * Whether to use wp-admin pages rather than Calypso. |
||
599 | * |
||
600 | * @return bool |
||
601 | */ |
||
602 | public function should_link_to_wp_admin() { |
||
605 | } |
||
606 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.