Completed
Push — try/seperate-publicize-handlin... ( 849cf0 )
by
unknown
31:45 queued 22:53
created

keyring-jetpack.php ➔ disconnect()   A

Complexity

Conditions 2

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
dl 11
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
4
5
class Keyring {
6
7
	function __construct() {
8
9
		add_action( 'load-settings_page_sharing', array( $this, 'admin_page_load' ), 9 );
10
11
	}
12
13
	function display_connection_error() {
14
		$code = false;
15
		if ( isset( $_GET['service'] ) ) {
16
			$service_name = $_GET['service'];
17
			$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 ) );
18
		} else {
19
			if ( isset( $_GET['publicize_error'] ) ) {
20
				$code = strtolower( $_GET['publicize_error'] );
21
				switch ( $code ) {
22
					case '400':
23
						$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' );
24
						break;
25
					case 'secret_mismatch':
26
						$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' );
27
						break;
28
					case 'empty_blog_id':
29
						$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' );
30
						break;
31
					case 'empty_state':
32
						$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() );
33
						break;
34
					default:
35
						$error = __( 'Something which should never happen, happened. Sorry about that. If you try again, maybe it will work.', 'jetpack' );
36
						break;
37
				}
38
			} else {
39
				$error = __( 'There was a problem connecting with Publicize. Please try again in a moment.', 'jetpack' );
40
			}
41
		}
42
		// Using the same formatting/style as Jetpack::admin_notices() error
43
		?>
44
		<div id="message" class="jetpack-message jetpack-err">
45
			<div class="squeezer">
46
				<h2><?php echo wp_kses( $error, array( 'a'      => array( 'href' => true ),
47
														'code'   => true,
48
														'strong' => true,
49
														'br'     => true,
50
														'b'      => true
51
					) ); ?></h2>
52
				<?php if ( $code ) : ?>
0 ignored issues
show
Bug Best Practice introduced by
The expression $code of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
53
					<p><?php printf( __( 'Error code: %s', 'jetpack' ), esc_html( stripslashes( $code ) ) ); ?></p>
54
				<?php endif; ?>
55
			</div>
56
		</div>
57
		<?php
58
	}
59
60
	function admin_page_load() {
61
		if ( isset( $_GET['action'] ) ) {
62
			if ( isset( $_GET['service'] ) ) {
63
				$service_name = $_GET['service'];
64
			}
65
66
			switch ( $_GET['action'] ) {
67
				case 'error':
68
					add_action( 'pre_admin_screen_sharing', array( $this, 'display_connection_error' ), 9 );
69
					break;
70
71
				case 'request':
72
					check_admin_referer( 'keyring-request', 'kr_nonce' );
73
					check_admin_referer( "keyring-request-$service_name", 'nonce' );
0 ignored issues
show
Bug introduced by
The variable $service_name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
74
75
					$verification = Jetpack::generate_secrets( 'publicize' );
76
					if ( ! $verification ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $verification of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
77
						$url = Jetpack::admin_url( 'jetpack#/settings' );
78
						wp_die( sprintf( __( "Jetpack is not connected. Please connect Jetpack by visiting <a href='%s'>Settings</a>.", 'jetpack' ), $url ) );
79
80
					}
81
					$stats_options = get_option( 'stats_options' );
82
					$wpcom_blog_id = Jetpack_Options::get_option( 'id' );
83
					$wpcom_blog_id = ! empty( $wpcom_blog_id ) ? $wpcom_blog_id : $stats_options['blog_id'];
84
85
					$user     = wp_get_current_user();
86
					$redirect = $this->api_url( $service_name, urlencode_deep( array(
87
						'action'       => 'request',
88
						'redirect_uri' => add_query_arg( array( 'action' => 'done' ), menu_page_url( 'sharing', false ) ),
89
						'for'          => 'publicize',
90
						// required flag that says this connection is intended for publicize
91
						'siteurl'      => site_url(),
92
						'state'        => $user->ID,
93
						'blog_id'      => $wpcom_blog_id,
94
						'secret_1'     => $verification['secret_1'],
95
						'secret_2'     => $verification['secret_2'],
96
						'eol'          => $verification['exp'],
97
					) ) );
98
					wp_redirect( $redirect );
99
					exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method admin_page_load() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
100
					break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

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, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
101
102
				case 'completed':
103
					Jetpack::load_xml_rpc_client();
104
					$xml = new Jetpack_IXR_Client();
105
					$xml->query( 'jetpack.fetchPublicizeConnections' );
106
107
					if ( ! $xml->isError() ) {
108
						$response = $xml->getResponse();
109
						Jetpack_Options::update_option( 'publicize_connections', $response );
110
					}
111
112
					break;
113
114
				case 'delete':
115
					$id = $_GET['id'];
116
117
					check_admin_referer( 'keyring-request', 'kr_nonce' );
118
					check_admin_referer( "keyring-request-$service_name", 'nonce' );
119
120
					$this->disconnect( $service_name, $id );
0 ignored issues
show
Bug introduced by
The method disconnect() does not exist on Keyring. Did you maybe mean disconnect_url()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
121
122
					add_action( 'admin_notices', array( $this, 'display_disconnected' ) );
123
					break;
124
			}
125
		}
126
127
	/**
128
	 * Remove a Publicize connection
129
	 */
130 View Code Duplication
	function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
		Jetpack::load_xml_rpc_client();
132
		$xml = new Jetpack_IXR_Client();
133
		$xml->query( 'jetpack.deletePublicizeConnection', $connection_id );
134
135
		if ( ! $xml->isError() ) {
136
			Jetpack_Options::update_option( 'publicize_connections', $xml->getResponse() );
137
		} else {
138
			return false;
139
		}
140
	}
141
142
		// Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
143
		// Errors encountered on WordPress.com's end are passed back as a code
144
		/*
145
		if ( isset( $_GET['action'] ) && 'error' == $_GET['action'] ) {
146
			// Load Jetpack's styles to handle the box
147
			Jetpack::init()->admin_styles();
148
		}
149
		*/
150
	}
151
152
	/**
153
	 * Gets a URL to the public-api actions. Works like WP's admin_url
154
	 *
155
	 * @param string $service Shortname of a specific service.
156
	 *
157
	 * @return URL to specific public-api process
158
	 */
159
	// on WordPress.com this is/calls Keyring::admin_url
160
	function api_url( $service = false, $params = array() ) {
161
		/**
162
		 * Filters the API URL used to interact with WordPress.com.
163
		 *
164
		 * @module publicize
165
		 *
166
		 * @since 2.0.0
167
		 *
168
		 * @param string https://public-api.wordpress.com/connect/?jetpack=publicize Default Publicize API URL.
169
		 */
170
		$url = apply_filters( 'publicize_api_url', 'https://public-api.wordpress.com/connect/?jetpack=publicize' );
171
172
		if ( $service ) {
173
			$url = add_query_arg( array( 'service' => $service ), $url );
174
		}
175
176
		if ( count( $params ) ) {
177
			$url = add_query_arg( $params, $url );
178
		}
179
180
		return $url;
181
	}
182
183 View Code Duplication
	static function connect_url( $service_name ) {
184
		return add_query_arg( array(
185
			'action'   => 'request',
186
			'service'  => $service_name,
187
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
188
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
189
		), menu_page_url( 'sharing', false ) );
190
	}
191
192
	static function refresh_url( $service_name ) {
193
		return add_query_arg( array(
194
			'action'   => 'request',
195
			'service'  => $service_name,
196
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
197
			'refresh'  => 1,
198
			'for'      => 'publicize',
199
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
200
		), admin_url( 'options-general.php?page=sharing' ) );
201
	}
202
203 View Code Duplication
	static function disconnect_url( $service_name, $id ) {
204
		return add_query_arg( array(
205
			'action'   => 'delete',
206
			'service'  => $service_name,
207
			'id'       => $id,
208
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
209
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
210
		), menu_page_url( 'sharing', false ) );
211
	}
212
213
	function get_services() {
214
215
		$services = array();
216
217
		if ( Jetpack::is_module_active( 'publicize' ) ) {
218
			$publicize = publicize_init();
219
 			$services = array_concat( $services, array_keys( $publicize->get_services( 'all' ) ) );
220
		}
221
222
		return $services;
223
224
	}
225
226
}
227