Completed
Push — branch-4.2 ( f12916...1c7f7d )
by Jeremy
11:38
created

Publicize::options_page_google_plus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
class Publicize extends Publicize_Base {
4
5
	function __construct() {
6
		parent::__construct();
7
8
		add_filter( 'jetpack_xmlrpc_methods', array( $this, 'register_update_publicize_connections_xmlrpc_method' ) );
9
10
		add_action( 'load-settings_page_sharing', array( $this, 'admin_page_load' ), 9 );
11
12
		add_action( 'wp_ajax_publicize_tumblr_options_page', array( $this, 'options_page_tumblr' ) );
13
		add_action( 'wp_ajax_publicize_facebook_options_page', array( $this, 'options_page_facebook' ) );
14
		add_action( 'wp_ajax_publicize_twitter_options_page', array( $this, 'options_page_twitter' ) );
15
		add_action( 'wp_ajax_publicize_linkedin_options_page', array( $this, 'options_page_linkedin' ) );
16
		add_action( 'wp_ajax_publicize_path_options_page', array( $this, 'options_page_path' ) );
17
		add_action( 'wp_ajax_publicize_google_plus_options_page', array( $this, 'options_page_google_plus' ) );
18
19
		add_action( 'wp_ajax_publicize_tumblr_options_save', array( $this, 'options_save_tumblr' ) );
20
		add_action( 'wp_ajax_publicize_facebook_options_save', array( $this, 'options_save_facebook' ) );
21
		add_action( 'wp_ajax_publicize_twitter_options_save', array( $this, 'options_save_twitter' ) );
22
		add_action( 'wp_ajax_publicize_linkedin_options_save', array( $this, 'options_save_linkedin' ) );
23
		add_action( 'wp_ajax_publicize_path_options_save', array( $this, 'options_save_path' ) );
24
		add_action( 'wp_ajax_publicize_google_plus_options_save', array( $this, 'options_save_google_plus' ) );
25
26
		add_action( 'load-settings_page_sharing', array( $this, 'force_user_connection' ) );
27
28
		add_filter( 'publicize_checkbox_default', array( $this, 'publicize_checkbox_default' ), 10, 4 );
29
30
		add_action( 'wp_insert_post', array( $this, 'save_publicized' ), 11, 3 );
31
32
		add_filter( 'jetpack_twitter_cards_site_tag', array( $this, 'enhaced_twitter_cards_site_tag' ) );
33
34
		add_action( 'publicize_save_meta', array( $this, 'save_publicized_twitter_account' ), 10, 4 );
35
		add_action( 'publicize_save_meta', array( $this, 'save_publicized_facebook_account' ), 10, 4 );
36
37
		add_filter( 'jetpack_sharing_twitter_via', array( $this, 'get_publicized_twitter_account' ), 10, 2 );
38
39
		include_once ( JETPACK__PLUGIN_DIR . 'modules/publicize/enhanced-open-graph.php' );
40
	}
41
42
	function force_user_connection() {
43
		global $current_user;
44
		$user_token = Jetpack_Data::get_access_token( $current_user->ID );
45
		$is_user_connected = $user_token && !is_wp_error( $user_token );
46
47
		// If the user is already connected via Jetpack, then we're good
48
		if ( $is_user_connected )
49
			return;
50
51
		// If they're not connected, then remove the Publicize UI and tell them they need to connect first
52
		global $publicize_ui;
53
		remove_action( 'pre_admin_screen_sharing', array( $publicize_ui, 'admin_page' ) );
54
55
		// Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
56
		// Jetpack::init()->admin_styles();
57
		add_action( 'pre_admin_screen_sharing', array( $this, 'admin_page_warning' ), 1 );
58
	}
59
60
	function admin_page_warning() {
61
		$jetpack = Jetpack::init();
62
		$blog_name = get_bloginfo( 'blogname' );
63
		if ( empty( $blog_name ) ) {
64
			$blog_name = home_url( '/' );
65
		}
66
67
		?>
68
		<div id="message" class="updated jetpack-message jp-connect">
69
			<div class="jetpack-wrap-container">
70
				<div class="jetpack-text-container">
71
					<p><?php printf(
72
						esc_html( wptexturize( __( "To use Publicize, you'll need to link your %s account to your WordPress.com account using the link below.", 'jetpack' ) ) ),
73
						'<strong>' . esc_html( $blog_name ) . '</strong>'
74
					); ?></p>
75
					<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>
76
				</div>
77
				<div class="jetpack-install-container">
78
					<p class="submit"><a href="<?php echo $jetpack->build_connect_url( false, menu_page_url( 'sharing', false ) ); ?>" class="button-connector" id="wpcom-connect"><?php esc_html_e( 'Link account with WordPress.com', 'jetpack' ); ?></a></p>
79
				</div>
80
			</div>
81
		</div>
82
		<?php
83
	}
84
85
	/**
86
	 * Remove a Publicize connection
87
	 */
88
	function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) {
89
		Jetpack::load_xml_rpc_client();
90
		$xml = new Jetpack_IXR_Client();
91
		$xml->query( 'jetpack.deletePublicizeConnection', $connection_id );
92
93
		if ( ! $xml->isError() ) {
94
			Jetpack_Options::update_option( 'publicize_connections', $xml->getResponse() );
95
		} else {
96
			return false;
97
		}
98
	}
99
100
	function receive_updated_publicize_connections( $publicize_connections ) {
101
		Jetpack_Options::update_option( 'publicize_connections', $publicize_connections );
102
		return true;
103
	}
104
105
	function register_update_publicize_connections_xmlrpc_method( $methods ) {
106
		return array_merge( $methods, array(
107
			'jetpack.updatePublicizeConnections' => array( $this, 'receive_updated_publicize_connections' ),
108
		) );
109
	}
110
111
	function get_connections( $service_name, $_blog_id = false, $_user_id = false ) {
112
		$connections = Jetpack_Options::get_option( 'publicize_connections' );
113
		$connections_to_return = array();
114
		if ( !empty( $connections ) && is_array( $connections ) ) {
115
			if ( !empty( $connections[$service_name] ) ) {
116
				foreach( $connections[$service_name] as $id => $connection ) {
117
					if ( 0 == $connection['connection_data']['user_id'] || $this->user_id() == $connection['connection_data']['user_id'] ) {
118
						$connections_to_return[$id] = $connection;
119
					}
120
				}
121
			}
122
			return $connections_to_return;
123
		}
124
		return false;
125
	}
126
127
	function get_connection_id( $connection ) {
128
		return $connection['connection_data']['id'];
129
	}
130
131
	function get_connection_meta( $connection ) {
132
		$connection['user_id'] = $connection['connection_data']['user_id']; // Allows for shared connections
133
		return $connection;
134
	}
135
136
	function admin_page_load() {
137
		if ( isset( $_GET['action'] ) ) {
138
			if ( isset( $_GET['service'] ) )
139
				$service_name = $_GET['service'];
140
141
			switch ( $_GET['action'] ) {
142
			case 'error':
143
				add_action( 'pre_admin_screen_sharing', array( $this, 'display_connection_error' ), 9 );
144
				break;
145
146
			case 'request':
147
				check_admin_referer( 'keyring-request', 'kr_nonce' );
148
				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...
149
150
				$verification = Jetpack::create_nonce( 'publicize' );
151
152
				$stats_options = get_option( 'stats_options' );
153
				$wpcom_blog_id = Jetpack_Options::get_option('id');
154
				$wpcom_blog_id = !empty( $wpcom_blog_id ) ? $wpcom_blog_id : $stats_options['blog_id'];
155
156
				$user = wp_get_current_user();
157
				$redirect = $this->api_url( $service_name, urlencode_deep( array(
158
					'action'       => 'request',
159
					'redirect_uri' => add_query_arg( array( 'action' => 'done' ), menu_page_url( 'sharing', false ) ),
160
					'for'          => 'publicize', // required flag that says this connection is intended for publicize
161
					'siteurl'      => site_url(),
162
					'state'        => $user->ID,
163
					'blog_id'      => $wpcom_blog_id,
164
					'secret_1'	   => $verification['secret_1'],
165
					'secret_2'     => $verification['secret_2'],
166
					'eol'		   => $verification['eol'],
167
				) ) );
168
				wp_redirect( $redirect );
169
				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...
170
				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...
171
172
			case 'completed':
173
				Jetpack::load_xml_rpc_client();
174
				$xml = new Jetpack_IXR_Client();
175
				$xml->query( 'jetpack.fetchPublicizeConnections' );
176
177
				if ( ! $xml->isError() ) {
178
					$response = $xml->getResponse();
179
					Jetpack_Options::update_option( 'publicize_connections', $response );
180
				}
181
182
				break;
183
184
			case 'delete':
185
				$id = $_GET['id'];
186
187
				check_admin_referer( 'keyring-request', 'kr_nonce' );
188
				check_admin_referer( "keyring-request-$service_name", 'nonce' );
189
190
				$this->disconnect( $service_name, $id );
191
192
				add_action( 'admin_notices', array( $this, 'display_disconnected' ) );
193
				break;
194
			}
195
		}
196
197
		// Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
198
		// Errors encountered on WordPress.com's end are passed back as a code
199
		/*
200
		if ( isset( $_GET['action'] ) && 'error' == $_GET['action'] ) {
201
			// Load Jetpack's styles to handle the box
202
			Jetpack::init()->admin_styles();
203
		}
204
		*/
205
	}
206
207
	function display_connection_error() {
208
		$code = false;
209
		if ( isset( $_GET['service'] ) ) {
210
			$service_name = $_GET['service'];
211
			$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 ) );
212
		} else {
213
			if ( isset( $_GET['publicize_error'] ) ) {
214
				$code = strtolower( $_GET['publicize_error'] );
215
				switch ( $code ) {
216
				case '400':
217
					$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' );
218
					break;
219
				case 'secret_mismatch':
220
					$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' );
221
					break;
222
				case 'empty_blog_id':
223
					$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' );
224
					break;
225
				case 'empty_state':
226
					$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() );
227
					break;
228
				default:
229
					$error = __( 'Something which should never happen, happened. Sorry about that. If you try again, maybe it will work.', 'jetpack' );
230
					break;
231
				}
232
			} else {
233
				$error = __( 'There was a problem connecting with Publicize. Please try again in a moment.', 'jetpack' );
234
			}
235
		}
236
		// Using the same formatting/style as Jetpack::admin_notices() error
237
		?>
238
		<div id="message" class="jetpack-message jetpack-err">
239
			<div class="squeezer">
240
				<h2><?php echo wp_kses( $error, array( 'a' => array( 'href' => true ), 'code' => true, 'strong' => true, 'br' => true, 'b' => true ) ); ?></h2>
241
				<?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...
242
				<p><?php printf( __( 'Error code: %s', 'jetpack' ), esc_html( stripslashes( $code ) ) ); ?></p>
243
				<?php endif; ?>
244
			</div>
245
		</div>
246
		<?php
247
	}
248
249
	function display_disconnected() {
250
		echo "<div class='updated'>\n";
251
		echo '<p>' . esc_html( __( 'That connection has been removed.', 'jetpack' ) ) . "</p>\n";
252
		echo "</div>\n\n";
253
	}
254
255
	function globalization() {
256
		if ( 'on' == $_REQUEST['global'] ) {
257
			$id = $_REQUEST['connection'];
258
259
			if ( !current_user_can( $this->GLOBAL_CAP ) )
260
				return;
261
262
			Jetpack::load_xml_rpc_client();
263
			$xml = new Jetpack_IXR_Client();
264
			$xml->query( 'jetpack.globalizePublicizeConnection', $id, 'globalize' );
265
266
			if ( !$xml->isError() ) {
267
				$response = $xml->getResponse();
268
				Jetpack_Options::update_option( 'publicize_connections', $response );
269
			}
270
		}
271
	}
272
273
	/**
274
	* Gets a URL to the public-api actions. Works like WP's admin_url
275
	*
276
	* @param string $service Shortname of a specific service.
277
	* @return URL to specific public-api process
278
	*/
279
	// on WordPress.com this is/calls Keyring::admin_url
280
	function api_url( $service = false, $params = array() ) {
281
		/**
282
		 * Filters the API URL used to interact with WordPress.com.
283
		 *
284
		 * @module publicize
285
		 *
286
		 * @since 2.0.0
287
		 *
288
		 * @param string https://public-api.wordpress.com/connect/?jetpack=publicize Default Publicize API URL.
289
		 */
290
		$url = apply_filters( 'publicize_api_url', 'https://public-api.wordpress.com/connect/?jetpack=publicize' );
291
292
		if ( $service )
293
			$url = add_query_arg( array( 'service' => $service ), $url );
294
295
		if ( count ( $params ) )
296
			$url = add_query_arg( $params, $url );
297
298
		return $url;
299
	}
300
301 View Code Duplication
	function connect_url( $service_name ) {
302
		return add_query_arg( array(
303
			'action'   => 'request',
304
			'service'  =>  $service_name,
305
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
306
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
307
		), menu_page_url( 'sharing', false ) );
308
	}
309
310
	function refresh_url( $service_name ) {
311
		return add_query_arg( array(
312
			'action'   => 'request',
313
			'service'  => $service_name,
314
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
315
			'refresh'  => 1,
316
			'for'      => 'publicize',
317
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
318
		), admin_url( 'options-general.php?page=sharing' ) );
319
	}
320
321 View Code Duplication
	function disconnect_url( $service_name, $id ) {
322
		return add_query_arg( array (
323
			'action'   => 'delete',
324
			'service'  => $service_name,
325
			'id'       => $id,
326
			'kr_nonce' => wp_create_nonce( 'keyring-request' ),
327
			'nonce'    => wp_create_nonce( "keyring-request-$service_name" ),
328
		), menu_page_url( 'sharing', false ) );
329
	}
330
331
	function get_services( $filter ) {
332
		if ( !in_array( $filter, array( 'all', 'connected' ) ) )
333
			$filter = 'all';
334
335
		$services = array(
336
				'facebook'        => array(),
337
				'twitter'         => array(),
338
				'linkedin'        => array(),
339
				'tumblr'          => array(),
340
				'path'            => array(),
341
				'google_plus'     => array(),
342
		);
343
344
		if ( 'all' == $filter ) {
345
			return $services;
346
		} else {
347
			$connected_services = array();
348
			foreach ( $services as $service => $empty ) {
349
				$connections = $this->get_connections( $service );
350
				if ( $connections )
351
					$connected_services[$service] = $connections;
352
			}
353
			return $connected_services;
354
		}
355
	}
356
357
	function get_connection( $service, $id, $_blog_id = false, $_user_id = false ) {
358
		// Stub
359
	}
360
361
	function flag_post_for_publicize( $new_status, $old_status, $post ) {
362
		if ( 'publish' == $new_status && 'publish' != $old_status ) {
363
			/**
364
			 * Determines whether a post being published gets publicized.
365
			 *
366
			 * Side-note: Possibly our most alliterative filter name.
367
			 *
368
			 * @module publicize
369
			 *
370
			 * @since 4.1.0
371
			 *
372
			 * @param bool $should_publicize Should the post be publicized? Default to true.
373
			 * @param WP_POST $post Current Post object.
374
			 */
375
			$should_publicize = apply_filters( 'publicize_should_publicize_published_post', true, $post );
376
377
			if ( $should_publicize ) {
378
				update_post_meta( $post->ID, $this->PENDING, true );
379
			}
380
		}
381
	}
382
383
	function test_connection( $service_name, $connection ) {
384
		$connection_test_passed = true;
385
		$connection_test_message = '';
386
		$user_can_refresh = false;
0 ignored issues
show
Unused Code introduced by
$user_can_refresh is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
387
388
		$id = $this->get_connection_id( $connection );
389
390
		Jetpack::load_xml_rpc_client();
391
		$xml = new Jetpack_IXR_Client();
392
		$xml->query( 'jetpack.testPublicizeConnection', $id );
393
394
		if ( $xml->isError() ) {
395
			$xml_response = $xml->getResponse();
396
			$connection_test_message = $xml_response['faultString'];
397
			$connection_test_passed = false;
398
		}
399
400
		// Bail if all is well
401
		if ( $connection_test_passed ) {
402
			return true;
403
		}
404
405
		// Set up refresh if the user can
406
		$user_can_refresh = current_user_can( $this->GLOBAL_CAP );
407
		if ( $user_can_refresh ) {
408
			$nonce = wp_create_nonce( "keyring-request-" . $service_name );
0 ignored issues
show
Unused Code introduced by
$nonce is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
409
			$refresh_text = sprintf( _x( 'Refresh connection with %s', 'Refresh connection with {social media service}', 'jetpack' ), $this->get_service_label( $service_name ) );
410
			$refresh_url = $this->refresh_url( $service_name );
411
		}
412
413
		$error_data = array(
414
			'user_can_refresh' => $user_can_refresh,
415
			'refresh_text' => $refresh_text,
0 ignored issues
show
Bug introduced by
The variable $refresh_text 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...
416
			'refresh_url' => $refresh_url
0 ignored issues
show
Bug introduced by
The variable $refresh_url 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...
417
		);
418
419
		return new WP_Error( 'pub_conn_test_failed', $connection_test_message, $error_data );
420
	}
421
422
	/**
423
	 * Save a flag locally to indicate that this post has already been Publicized via the selected
424
	 * connections.
425
	 */
426
	function save_publicized( $post_ID, $post, $update ) {
0 ignored issues
show
Unused Code introduced by
The parameter $update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
427
		// Only do this when a post transitions to being published
428
		if ( get_post_meta( $post->ID, $this->PENDING ) ) {
429
430
			/**
431
			 * Fires when a post is saved that has is marked as pending publicizing
432
			 *
433
			 * @since 4.1.0
434
			 *
435
			 * @param int The post ID
436
			 */
437
			do_action( 'jetpack_publicize_post', $post->ID );
438
			delete_post_meta( $post->ID, $this->PENDING );
439
			update_post_meta( $post->ID, $this->POST_DONE . 'all', true );
440
		}
441
	}
442
443
	/**
444
	* Options Code
445
	*/
446
447
	function options_page_facebook() {
448
		$connected_services = Jetpack_Options::get_option( 'publicize_connections' );
449
		$connection = $connected_services['facebook'][$_REQUEST['connection']];
450
		$options_to_show = ( ! empty( $connection['connection_data']['meta']['options_responses'] ) ? $connection['connection_data']['meta']['options_responses'] : false );
451
452
		// Nonce check
453
		check_admin_referer( 'options_page_facebook_' . $_REQUEST['connection'] );
454
455
		$me    = ( ! empty( $options_to_show[0] )         ? $options_to_show[0]         : false );
456
		$pages = ( ! empty( $options_to_show[1]['data'] ) ? $options_to_show[1]['data'] : false );
457
458
		$profile_checked = true;
459
		$page_selected = false;
460
461
		if ( !empty( $connection['connection_data']['meta']['facebook_page'] ) ) {
462
			$found = false;
463
			if ( is_array( $pages->data ) ) {
464
				foreach ( $pages->data as $page ) {
465
					if ( $page->id == $connection['connection_data']['meta']['facebook_page'] ) {
466
						$found = true;
467
						break;
468
					}
469
				}
470
			}
471
472
			if ( $found ) {
473
				$profile_checked = false;
474
				$page_selected = $connection['connection_data']['meta']['facebook_page'];
475
			}
476
		}
477
478
		?>
479
480
		<div id="thickbox-content">
481
482
			<?php
483
			ob_start();
484
			Publicize_UI::connected_notice( 'Facebook' );
485
			$update_notice = ob_get_clean();
486
487
			if ( ! empty( $update_notice ) )
488
				echo $update_notice;
489
			?>
490
491
			<?php if ( !empty( $me['name'] ) ) : ?>
492
			<p><?php printf(
493
				esc_html__( 'Publicize to my %s:', 'jetpack' ),
494
				'<strong>' . esc_html__( 'Facebook Wall', 'jetpack' ) . '</strong>'
495
			); ?></p>
496
			<table id="option-profile">
497
				<tbody>
498
					<tr>
499
						<td class="radio"><input type="radio" name="option" data-type="profile" id="<?php echo esc_attr( $me['id'] ) ?>" value="" <?php checked( $profile_checked, true ); ?> /></td>
500
						<td class="thumbnail"><label for="<?php echo esc_attr( $me['id'] ) ?>"><img src="<?php echo esc_url( $me['picture']['data']['url'] ) ?>" width="50" height="50" /></label></td>
501
						<td class="details"><label for="<?php echo esc_attr( $me['id'] ) ?>"><?php echo esc_html( $me['name'] ) ?></label></td>
502
					</tr>
503
				</tbody>
504
			</table>
505
			<?php endif; ?>
506
507
			<?php if ( $pages ) : ?>
508
509
				<p><?php printf(
510
					esc_html__( 'Publicize to my %s:', 'jetpack' ),
511
					'<strong>' . esc_html__( 'Facebook Page', 'jetpack' ) . '</strong>'
512
				); ?></p>
513
				<table id="option-fb-fanpage">
514
					<tbody>
515
516
						<?php foreach ( $pages as $i => $page ) : ?>
517
							<?php if ( ! ( $i % 2 ) ) : ?>
518
								<tr>
519
							<?php endif; ?>
520
									<td class="radio"><input type="radio" name="option" data-type="page" id="<?php echo esc_attr( $page['id'] ) ?>" value="<?php echo esc_attr( $page['id'] ) ?>" <?php checked( $page_selected && $page_selected == $page['id'], true ); ?> /></td>
521
									<td class="thumbnail"><label for="<?php echo esc_attr( $page['id'] ) ?>"><img src="<?php echo esc_url( str_replace( '_s', '_q', $page['picture']['data']['url'] ) ) ?>" width="50" height="50" /></label></td>
522
									<td class="details">
523
										<label for="<?php echo esc_attr( $page['id'] ) ?>">
524
											<span class="name"><?php echo esc_html( $page['name'] ) ?></span><br/>
525
											<span class="category"><?php echo esc_html( $page['category'] ) ?></span>
526
										</label>
527
									</td>
528
							<?php if ( ( $i % 2 ) || ( $i == count( $pages ) - 1 ) ): ?>
529
								</tr>
530
							<?php endif; ?>
531
						<?php endforeach; ?>
532
533
					</tbody>
534
				</table>
535
536
			<?php endif; ?>
537
538
			<?php Publicize_UI::global_checkbox( 'facebook', $_REQUEST['connection'] ); ?>
539
540
			<p style="text-align: center;">
541
				<input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>" class="button fb-options save-options" name="save" data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>" rel="<?php echo wp_create_nonce('save_fb_token_' . $_REQUEST['connection'] ) ?>" />
542
			</p><br/>
543
		</div>
544
545
		<?php
546
	}
547
548
	function options_save_facebook() {
549
		// Nonce check
550
		check_admin_referer( 'save_fb_token_' . $_REQUEST['connection'] );
551
552
		$id = $_POST['connection'];
553
554
		// Check for a numeric page ID
555
		$page_id = $_POST['selected_id'];
556
		if ( !ctype_digit( $page_id ) )
557
			die( 'Security check' );
0 ignored issues
show
Coding Style Compatibility introduced by
The method options_save_facebook() 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...
558
559
		if ( isset( $_POST['selected_id'] ) && 'profile' == $_POST['type'] ) {
560
			// Publish to User Wall/Profile
561
			$options = array(
562
				'facebook_page'       => null,
563
				'facebook_profile'    => true
564
			);
565
566
		} else {
567
			if ( 'page' != $_POST['type'] || !isset( $_POST['selected_id'] ) ) {
568
				return;
569
			}
570
571
			// Publish to Page
572
			$options = array(
573
				'facebook_page'       => $page_id,
574
				'facebook_profile'    => null
575
			);
576
		}
577
578
		Jetpack::load_xml_rpc_client();
579
		$xml = new Jetpack_IXR_Client();
580
		$xml->query( 'jetpack.setPublicizeOptions', $id, $options );
581
582
		if ( !$xml->isError() ) {
583
			$response = $xml->getResponse();
584
			Jetpack_Options::update_option( 'publicize_connections', $response );
585
		}
586
587
		$this->globalization();
588
	}
589
590
	function options_page_tumblr() {
591
		// Nonce check
592
		check_admin_referer( 'options_page_tumblr_' . $_REQUEST['connection'] );
593
594
		$connected_services = Jetpack_Options::get_option( 'publicize_connections' );
595
		$connection = $connected_services['tumblr'][$_POST['connection']];
596
		$options_to_show = $connection['connection_data']['meta']['options_responses'];
597
		$request = $options_to_show[0];
598
599
		$blogs = $request['response']['user']['blogs'];
600
601
		$blog_selected = false;
602
603
		if ( !empty( $connection['connection_data']['meta']['tumblr_base_hostname'] ) ) {
604
			foreach ( $blogs as $blog ) {
605
				if ( $connection['connection_data']['meta']['tumblr_base_hostname'] == $this->get_basehostname( $blog['url'] ) ) {
606
					$blog_selected = $connection['connection_data']['meta']['tumblr_base_hostname'];
607
					break;
608
				}
609
			}
610
611
		}
612
613
		// Use their Primary blog if they haven't selected one yet
614
		if ( !$blog_selected ) {
615
			foreach ( $blogs as $blog ) {
616
				if ( $blog['primary'] )
617
					$blog_selected = $this->get_basehostname( $blog['url'] );
618
			}
619
		} ?>
620
621
		<div id="thickbox-content">
622
623
			<?php
624
			ob_start();
625
			Publicize_UI::connected_notice( 'Tumblr' );
626
			$update_notice = ob_get_clean();
627
628
			if ( ! empty( $update_notice ) )
629
				echo $update_notice;
630
			?>
631
632
			<p><?php printf(
633
				esc_html__( 'Publicize to my %s:', 'jetpack' ),
634
				'<strong>' . esc_html__( 'Tumblr blog', 'jetpack' ) . '</strong>'
635
			); ?></p>
636
637
			<ul id="option-tumblr-blog">
638
639
			<?php
640
			foreach ( $blogs as $blog ) {
641
				$url = $this->get_basehostname( $blog['url'] ); ?>
642
				<li>
643
					<input type="radio" name="option" data-type="blog" id="<?php echo esc_attr( $url ) ?>" value="<?php echo esc_attr( $url ) ?>" <?php checked( $blog_selected == $url, true ); ?> />
644
					<label for="<?php echo esc_attr( $url ) ?>"><span class="name"><?php echo esc_html( $blog['title'] ) ?></span></label>
645
				</li>
646
			<?php } ?>
647
648
			</ul>
649
650
			<?php Publicize_UI::global_checkbox( 'tumblr', $_REQUEST['connection'] ); ?>
651
652
			<p style="text-align: center;">
653
				<input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>" class="button tumblr-options save-options" name="save" data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>" rel="<?php echo wp_create_nonce( 'save_tumblr_blog_' . $_REQUEST['connection'] ) ?>" />
654
			</p> <br />
655
		</div>
656
657
		<?php
658
	}
659
660
	function get_basehostname( $url ) {
661
		return parse_url( $url, PHP_URL_HOST );
662
	}
663
664
	function options_save_tumblr() {
665
		// Nonce check
666
		check_admin_referer( 'save_tumblr_blog_' . $_REQUEST['connection'] );
667
668
		$id = $_POST['connection'];
669
670
		$options = array( 'tumblr_base_hostname' => $_POST['selected_id'] );
671
672
		Jetpack::load_xml_rpc_client();
673
		$xml = new Jetpack_IXR_Client();
674
		$xml->query( 'jetpack.setPublicizeOptions', $id, $options );
675
676
		if ( !$xml->isError() ) {
677
			$response = $xml->getResponse();
678
			Jetpack_Options::update_option( 'publicize_connections', $response );
679
		}
680
681
		$this->globalization();
682
	}
683
684
	function options_page_twitter() { Publicize_UI::options_page_other( 'twitter' ); }
685
	function options_page_linkedin() { Publicize_UI::options_page_other( 'linkedin' ); }
686
	function options_page_path() { Publicize_UI::options_page_other( 'path' ); }
687
	function options_page_google_plus() { Publicize_UI::options_page_other( 'google_plus' ); }
688
689
	function options_save_twitter() { $this->options_save_other( 'twitter' ); }
690
	function options_save_linkedin() { $this->options_save_other( 'linkedin' ); }
691
	function options_save_path() { $this->options_save_other( 'path' ); }
692
	function options_save_google_plus() { $this->options_save_other( 'google_plus' ); }
693
694
	function options_save_other( $service_name ) {
695
		// Nonce check
696
		check_admin_referer( 'save_' . $service_name . '_token_' . $_REQUEST['connection'] );
697
		$this->globalization();
698
	}
699
700
	/**
701
	* Already-published posts should not be Publicized by default. This filter sets checked to
702
	* false if a post has already been published.
703
	*/
704
	function publicize_checkbox_default( $checked, $post_id, $name, $connection ) {
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $connection is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
705
		if ( 'publish' == get_post_status( $post_id ) )
706
			return false;
707
708
		return $checked;
709
	}
710
711
	/**
712
	* If there's only one shared connection to Twitter set it as twitter:site tag.
713
	*/
714
	function enhaced_twitter_cards_site_tag( $tag ) {
715
		$custom_site_tag = get_option( 'jetpack-twitter-cards-site-tag' );
716
		if( ! empty( $custom_site_tag ) )
717
			return $tag;
718
		if ( ! $this->is_enabled('twitter') )
719
			return $tag;
720
		$connections = $this->get_connections( 'twitter' );
721
		foreach ( $connections as $connection ) {
0 ignored issues
show
Bug introduced by
The expression $connections of type array|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
722
			$connection_meta = $this->get_connection_meta( $connection );
723
			if ( 0 == $connection_meta['connection_data']['user_id'] ) {
724
				// If the connection is shared
725
				return $this->get_display_name( 'twitter', $connection );
726
			}
727
		}
728
		return $tag;
729
	}
730
731
	function save_publicized_twitter_account( $submit_post, $post_id, $service_name, $connection ) {
732
		if ( 'twitter' == $service_name && $submit_post ) {
733
			$connection_meta = $this->get_connection_meta( $connection );
734
			$publicize_twitter_user = get_post_meta( $post_id, '_publicize_twitter_user' );
735
			if ( empty( $publicize_twitter_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
736
				update_post_meta( $post_id, '_publicize_twitter_user', $this->get_display_name( 'twitter', $connection ) );
737
			}
738
		}
739
	}
740
741
	function get_publicized_twitter_account( $account, $post_id ) {
742
		if ( ! empty( $account ) ) {
743
			return $account;
744
		}
745
		$account = get_post_meta( $post_id, '_publicize_twitter_user', true );
746
		if ( ! empty( $account ) ) {
747
			return $account;
748
		}
749
		return '';
750
	}
751
752
	/**
753
	* Save the Publicized Facebook account when publishing a post
754
	* Use only Personal accounts, not Facebook Pages
755
	*/
756
	function save_publicized_facebook_account( $submit_post, $post_id, $service_name, $connection ) {
757
		$connection_meta = $this->get_connection_meta( $connection );
758
		if ( 'facebook' == $service_name && isset( $connection_meta['connection_data']['meta']['facebook_profile'] ) && $submit_post ) {
759
			$publicize_facebook_user = get_post_meta( $post_id, '_publicize_facebook_user' );
760
			if ( empty( $publicize_facebook_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
761
				$profile_link = $this->get_profile_link( 'facebook', $connection );
762
763
				if ( false !== $profile_link ) {
764
					update_post_meta( $post_id, '_publicize_facebook_user', $profile_link );
765
				}
766
			}
767
		}
768
	}
769
}
770