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 Publicize 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 Publicize, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 3 | class Publicize extends Publicize_Base { |
||
| 4 | |||
| 5 | function __construct() { |
||
| 41 | |||
| 42 | function add_disconnect_notice() { |
||
| 43 | add_action( 'admin_notices', array( $this, 'display_disconnected' ) ); |
||
| 44 | } |
||
| 45 | |||
| 46 | function force_user_connection() { |
||
| 47 | global $current_user; |
||
| 48 | $user_token = Jetpack_Data::get_access_token( $current_user->ID ); |
||
| 49 | $is_user_connected = $user_token && ! is_wp_error( $user_token ); |
||
| 50 | |||
| 51 | // If the user is already connected via Jetpack, then we're good |
||
| 52 | if ( $is_user_connected ) { |
||
| 53 | return; |
||
| 54 | } |
||
| 55 | |||
| 56 | // If they're not connected, then remove the Publicize UI and tell them they need to connect first |
||
| 57 | global $publicize_ui; |
||
| 58 | remove_action( 'pre_admin_screen_sharing', array( $publicize_ui, 'admin_page' ) ); |
||
| 59 | |||
| 60 | // Do we really need `admin_styles`? With the new admin UI, it's breaking some bits. |
||
| 61 | // Jetpack::init()->admin_styles(); |
||
| 62 | add_action( 'pre_admin_screen_sharing', array( $this, 'admin_page_warning' ), 1 ); |
||
| 63 | } |
||
| 64 | |||
| 65 | function admin_page_warning() { |
||
| 66 | $jetpack = Jetpack::init(); |
||
| 67 | $blog_name = get_bloginfo( 'blogname' ); |
||
| 68 | if ( empty( $blog_name ) ) { |
||
| 69 | $blog_name = home_url( '/' ); |
||
| 70 | } |
||
| 71 | |||
| 72 | ?> |
||
| 73 | <div id="message" class="updated jetpack-message jp-connect"> |
||
| 74 | <div class="jetpack-wrap-container"> |
||
| 75 | <div class="jetpack-text-container"> |
||
| 76 | <p><?php printf( |
||
| 77 | /* translators: %s is the name of the blog */ |
||
| 78 | esc_html( wptexturize( __( "To use Publicize, you'll need to link your %s account to your WordPress.com account using the link below.", 'jetpack' ) ) ), |
||
| 79 | '<strong>' . esc_html( $blog_name ) . '</strong>' |
||
| 80 | ); ?></p> |
||
| 81 | <p><?php echo esc_html( wptexturize( __( "If you don't have a WordPress.com account yet, you can sign up for free in just a few seconds.", 'jetpack' ) ) ); ?></p> |
||
| 82 | </div> |
||
| 83 | <div class="jetpack-install-container"> |
||
| 84 | <p class="submit"><a |
||
| 85 | href="<?php echo $jetpack->build_connect_url( false, menu_page_url( 'sharing', false ) ); ?>" |
||
| 86 | class="button-connector" |
||
| 87 | id="wpcom-connect"><?php esc_html_e( 'Link account with WordPress.com', 'jetpack' ); ?></a> |
||
| 88 | </p> |
||
| 89 | <p class="jetpack-install-blurb"> |
||
| 90 | <?php jetpack_render_tos_blurb(); ?> |
||
| 91 | </p> |
||
| 92 | </div> |
||
| 93 | </div> |
||
| 94 | </div> |
||
| 95 | <?php |
||
| 96 | } |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Remove a Publicize connection |
||
| 100 | */ |
||
| 101 | function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) { |
||
| 102 | return Jetpack_Keyring_Service_Helper::disconnect( $service_name, $connection_id, $_blog_id, $_user_id, $force_delete ); |
||
| 103 | } |
||
| 104 | |||
| 105 | function receive_updated_publicize_connections( $publicize_connections ) { |
||
| 106 | Jetpack_Options::update_option( 'publicize_connections', $publicize_connections ); |
||
| 107 | |||
| 108 | return true; |
||
| 109 | } |
||
| 110 | |||
| 111 | function register_update_publicize_connections_xmlrpc_method( $methods ) { |
||
| 112 | return array_merge( $methods, array( |
||
| 113 | 'jetpack.updatePublicizeConnections' => array( $this, 'receive_updated_publicize_connections' ), |
||
| 114 | ) ); |
||
| 115 | } |
||
| 116 | |||
| 117 | function get_all_connections() { |
||
| 118 | $connections = Jetpack_Options::get_option( 'publicize_connections' ); |
||
| 119 | if ( isset( $connections['google_plus'] ) ) { |
||
| 120 | unset( $connections['google_plus'] ); |
||
| 121 | } |
||
| 122 | return $connections; |
||
| 123 | } |
||
| 124 | |||
| 125 | function get_connections( $service_name, $_blog_id = false, $_user_id = false ) { |
||
| 147 | |||
| 148 | function get_all_connections_for_user() { |
||
| 168 | |||
| 169 | function get_connection_id( $connection ) { |
||
| 172 | |||
| 173 | function get_connection_unique_id( $connection ) { |
||
| 176 | |||
| 177 | function get_connection_meta( $connection ) { |
||
| 181 | |||
| 182 | function admin_page_load() { |
||
| 183 | if ( isset( $_GET['action'] ) && 'error' === $_GET['action'] ) { |
||
| 184 | add_action( 'pre_admin_screen_sharing', array( $this, 'display_connection_error' ), 9 ); |
||
| 185 | } |
||
| 186 | } |
||
| 187 | |||
| 188 | function display_connection_error() { |
||
| 189 | $code = false; |
||
| 190 | if ( isset( $_GET['service'] ) ) { |
||
| 191 | $service_name = $_GET['service']; |
||
| 192 | $error = sprintf( __( 'There was a problem connecting to %s to create an authorized connection. Please try again in a moment.', 'jetpack' ), Publicize::get_service_label( $service_name ) ); |
||
| 193 | } else { |
||
| 194 | if ( isset( $_GET['publicize_error'] ) ) { |
||
| 195 | $code = strtolower( $_GET['publicize_error'] ); |
||
| 196 | switch ( $code ) { |
||
| 197 | case '400': |
||
| 198 | $error = __( 'An invalid request was made. This normally means that something intercepted or corrupted the request from your server to the Jetpack Server. Try again and see if it works this time.', 'jetpack' ); |
||
| 199 | break; |
||
| 200 | case 'secret_mismatch': |
||
| 201 | $error = __( 'We could not verify that your server is making an authorized request. Please try again, and make sure there is nothing interfering with requests from your server to the Jetpack Server.', 'jetpack' ); |
||
| 202 | break; |
||
| 203 | case 'empty_blog_id': |
||
| 204 | $error = __( 'No blog_id was included in your request. Please try disconnecting Jetpack from WordPress.com and then reconnecting it. Once you have done that, try connecting Publicize again.', 'jetpack' ); |
||
| 205 | break; |
||
| 206 | case 'empty_state': |
||
| 207 | $error = sprintf( __( 'No user information was included in your request. Please make sure that your user account has connected to Jetpack. Connect your user account by going to the <a href="%s">Jetpack page</a> within wp-admin.', 'jetpack' ), Jetpack::admin_url() ); |
||
| 208 | break; |
||
| 209 | default: |
||
| 210 | $error = __( 'Something which should never happen, happened. Sorry about that. If you try again, maybe it will work.', 'jetpack' ); |
||
| 211 | break; |
||
| 212 | } |
||
| 213 | } else { |
||
| 214 | $error = __( 'There was a problem connecting with Publicize. Please try again in a moment.', 'jetpack' ); |
||
| 215 | } |
||
| 216 | } |
||
| 217 | // Using the same formatting/style as Jetpack::admin_notices() error |
||
| 218 | ?> |
||
| 219 | <div id="message" class="jetpack-message jetpack-err"> |
||
| 220 | <div class="squeezer"> |
||
| 221 | <h2><?php echo wp_kses( $error, array( 'a' => array( 'href' => true ), |
||
| 222 | 'code' => true, |
||
| 223 | 'strong' => true, |
||
| 224 | 'br' => true, |
||
| 225 | 'b' => true |
||
| 226 | ) ); ?></h2> |
||
| 227 | <?php if ( $code ) : ?> |
||
|
|
|||
| 228 | <p><?php printf( __( 'Error code: %s', 'jetpack' ), esc_html( stripslashes( $code ) ) ); ?></p> |
||
| 229 | <?php endif; ?> |
||
| 230 | </div> |
||
| 231 | </div> |
||
| 232 | <?php |
||
| 233 | } |
||
| 234 | |||
| 235 | function display_disconnected() { |
||
| 236 | echo "<div class='updated'>\n"; |
||
| 237 | echo '<p>' . esc_html( __( 'That connection has been removed.', 'jetpack' ) ) . "</p>\n"; |
||
| 238 | echo "</div>\n\n"; |
||
| 239 | } |
||
| 240 | |||
| 241 | function globalization() { |
||
| 242 | if ( 'on' == $_REQUEST['global'] ) { |
||
| 243 | $globalize_connection = $_REQUEST['connection']; |
||
| 244 | if ( ! current_user_can( $this->GLOBAL_CAP ) ) { |
||
| 245 | return; |
||
| 246 | } |
||
| 247 | |||
| 248 | $this->globalize_connection( $globalize_connection ); |
||
| 249 | } |
||
| 250 | } |
||
| 251 | |||
| 252 | View Code Duplication | function globalize_connection( $connection_id ) { |
|
| 253 | Jetpack::load_xml_rpc_client(); |
||
| 254 | $xml = new Jetpack_IXR_Client(); |
||
| 255 | $xml->query( 'jetpack.globalizePublicizeConnection', $connection_id, 'globalize' ); |
||
| 256 | |||
| 257 | if ( ! $xml->isError() ) { |
||
| 258 | $response = $xml->getResponse(); |
||
| 259 | $this->receive_updated_publicize_connections( $response ); |
||
| 260 | } |
||
| 261 | } |
||
| 262 | |||
| 263 | View Code Duplication | function unglobalize_connection( $connection_id ) { |
|
| 264 | Jetpack::load_xml_rpc_client(); |
||
| 265 | $xml = new Jetpack_IXR_Client(); |
||
| 266 | $xml->query( 'jetpack.globalizePublicizeConnection', $connection_id, 'unglobalize' ); |
||
| 267 | |||
| 268 | if ( ! $xml->isError() ) { |
||
| 269 | $response = $xml->getResponse(); |
||
| 270 | $this->receive_updated_publicize_connections( $response ); |
||
| 271 | } |
||
| 272 | } |
||
| 273 | |||
| 274 | function connect_url( $service_name, $for = 'publicize' ) { |
||
| 275 | return Jetpack_Keyring_Service_Helper::connect_url( $service_name, $for ); |
||
| 276 | } |
||
| 277 | |||
| 278 | function refresh_url( $service_name, $for = 'publicize' ) { |
||
| 279 | return Jetpack_Keyring_Service_Helper::refresh_url( $service_name, $for ); |
||
| 280 | } |
||
| 281 | |||
| 282 | function disconnect_url( $service_name, $id ) { |
||
| 283 | return Jetpack_Keyring_Service_Helper::disconnect_url( $service_name, $id ); |
||
| 284 | } |
||
| 285 | |||
| 286 | /** |
||
| 287 | * Get social networks, either all available or only those that the site is connected to. |
||
| 288 | * |
||
| 289 | * @since 2.0.0 |
||
| 290 | * @since 6.6.0 Removed Path. Service closed October 2018. |
||
| 291 | * |
||
| 292 | * @param string $filter Select the list of services that will be returned. Defaults to 'all', accepts 'connected'. |
||
| 293 | * |
||
| 294 | * @return array List of social networks. |
||
| 295 | */ |
||
| 296 | function get_services( $filter = 'all', $_blog_id = false, $_user_id = false ) { |
||
| 297 | $services = array( |
||
| 298 | 'facebook' => array(), |
||
| 299 | 'twitter' => array(), |
||
| 300 | 'linkedin' => array(), |
||
| 301 | 'tumblr' => array(), |
||
| 302 | ); |
||
| 303 | |||
| 304 | View Code Duplication | if ( 'all' == $filter ) { |
|
| 305 | return $services; |
||
| 306 | } else { |
||
| 307 | $connected_services = array(); |
||
| 308 | foreach ( $services as $service_name => $empty ) { |
||
| 309 | $connections = $this->get_connections( $service_name, $_blog_id, $_user_id ); |
||
| 310 | if ( $connections ) { |
||
| 311 | $connected_services[ $service_name ] = $connections; |
||
| 312 | } |
||
| 313 | } |
||
| 314 | return $connected_services; |
||
| 315 | } |
||
| 316 | } |
||
| 317 | |||
| 318 | function get_connection( $service_name, $id, $_blog_id = false, $_user_id = false ) { |
||
| 321 | |||
| 322 | function flag_post_for_publicize( $new_status, $old_status, $post ) { |
||
| 347 | |||
| 348 | function test_connection( $service_name, $connection ) { |
||
| 380 | |||
| 381 | /** |
||
| 382 | * Checks if post has already been shared by Publicize in the past. |
||
| 383 | * |
||
| 384 | * Jetpack uses two methods: |
||
| 385 | * 1. A POST_DONE . 'all' postmeta flag, or |
||
| 386 | * 2. if the post has already been published. |
||
| 387 | * |
||
| 388 | * @since 6.7.0 |
||
| 389 | * |
||
| 390 | * @param integer $post_id Optional. Post ID to query connection status for: will use current post if missing. |
||
| 391 | * |
||
| 392 | * @return bool True if post has already been shared by Publicize, false otherwise. |
||
| 393 | */ |
||
| 394 | public function post_is_done_sharing( $post_id = null ) { |
||
| 395 | // Defaults to current post if $post_id is null. |
||
| 396 | $post = get_post( $post_id ); |
||
| 397 | if ( is_null( $post ) ) { |
||
| 398 | return false; |
||
| 399 | } |
||
| 400 | |||
| 401 | return 'publish' == $post->post_status || get_post_meta( $post->ID, $this->POST_DONE . 'all', true ); |
||
| 402 | } |
||
| 403 | |||
| 404 | /** |
||
| 405 | * Save a flag locally to indicate that this post has already been Publicized via the selected |
||
| 406 | * connections. |
||
| 407 | */ |
||
| 408 | function save_publicized( $post_ID, $post = null, $update = null ) { |
||
| 429 | |||
| 430 | function set_post_flags( $flags, $post ) { |
||
| 450 | |||
| 451 | /** |
||
| 452 | * Options Code |
||
| 453 | */ |
||
| 454 | |||
| 455 | function options_page_facebook() { |
||
| 546 | |||
| 547 | function options_save_facebook() { |
||
| 569 | |||
| 570 | function options_page_tumblr() { |
||
| 643 | |||
| 644 | function get_basehostname( $url ) { |
||
| 647 | |||
| 648 | function options_save_tumblr() { |
||
| 656 | |||
| 657 | View Code Duplication | function set_remote_publicize_options( $id, $options ) { |
|
| 668 | |||
| 669 | function options_page_twitter() { |
||
| 672 | |||
| 673 | function options_page_linkedin() { |
||
| 676 | |||
| 677 | function options_save_twitter() { |
||
| 678 | $this->options_save_other( 'twitter' ); |
||
| 679 | } |
||
| 680 | |||
| 681 | function options_save_linkedin() { |
||
| 682 | $this->options_save_other( 'linkedin' ); |
||
| 683 | } |
||
| 684 | |||
| 685 | function options_save_other( $service_name ) { |
||
| 686 | // Nonce check |
||
| 687 | check_admin_referer( 'save_' . $service_name . '_token_' . $_REQUEST['connection'] ); |
||
| 688 | $this->globalization(); |
||
| 689 | } |
||
| 690 | |||
| 691 | /** |
||
| 692 | * If there's only one shared connection to Twitter set it as twitter:site tag. |
||
| 693 | */ |
||
| 694 | function enhaced_twitter_cards_site_tag( $tag ) { |
||
| 713 | |||
| 714 | function save_publicized_twitter_account( $submit_post, $post_id, $service_name, $connection ) { |
||
| 723 | |||
| 724 | function get_publicized_twitter_account( $account, $post_id ) { |
||
| 735 | |||
| 736 | /** |
||
| 737 | * Save the Publicized Facebook account when publishing a post |
||
| 738 | * Use only Personal accounts, not Facebook Pages |
||
| 739 | */ |
||
| 740 | function save_publicized_facebook_account( $submit_post, $post_id, $service_name, $connection ) { |
||
| 753 | } |
||
| 754 |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: