Completed
Push — prepare/4.1 ( 0b4dc2...26fe0a )
by Jeremy
279:11 queued 269:16
created

Publicize::get_basehostname()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
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( 'transition_post_status', array( $this, 'save_publicized' ), 10, 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( $new_status, $old_status, $post ) {
427
		// Only do this when a post transitions to being published
428
		if ( 'publish' == $new_status && 'publish' != $old_status ) {
429
			update_post_meta( $post->ID, $this->POST_DONE . 'all', true );
430
		}
431
	}
432
433
	/**
434
	* Options Code
435
	*/
436
437
	function options_page_facebook() {
438
		$connected_services = Jetpack_Options::get_option( 'publicize_connections' );
439
		$connection = $connected_services['facebook'][$_REQUEST['connection']];
440
		$options_to_show = ( ! empty( $connection['connection_data']['meta']['options_responses'] ) ? $connection['connection_data']['meta']['options_responses'] : false );
441
442
		// Nonce check
443
		check_admin_referer( 'options_page_facebook_' . $_REQUEST['connection'] );
444
445
		$me    = ( ! empty( $options_to_show[0] )         ? $options_to_show[0]         : false );
446
		$pages = ( ! empty( $options_to_show[1]['data'] ) ? $options_to_show[1]['data'] : false );
447
448
		$profile_checked = true;
449
		$page_selected = false;
450
451
		if ( !empty( $connection['connection_data']['meta']['facebook_page'] ) ) {
452
			$found = false;
453
			if ( is_array( $pages->data ) ) {
454
				foreach ( $pages->data as $page ) {
455
					if ( $page->id == $connection['connection_data']['meta']['facebook_page'] ) {
456
						$found = true;
457
						break;
458
					}
459
				}
460
			}
461
462
			if ( $found ) {
463
				$profile_checked = false;
464
				$page_selected = $connection['connection_data']['meta']['facebook_page'];
465
			}
466
		}
467
468
		?>
469
470
		<div id="thickbox-content">
471
472
			<?php
473
			ob_start();
474
			Publicize_UI::connected_notice( 'Facebook' );
475
			$update_notice = ob_get_clean();
476
477
			if ( ! empty( $update_notice ) )
478
				echo $update_notice;
479
			?>
480
481
			<?php if ( !empty( $me['name'] ) ) : ?>
482
			<p><?php printf(
483
				esc_html__( 'Publicize to my %s:', 'jetpack' ),
484
				'<strong>' . esc_html__( 'Facebook Wall', 'jetpack' ) . '</strong>'
485
			); ?></p>
486
			<table id="option-profile">
487
				<tbody>
488
					<tr>
489
						<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>
490
						<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>
491
						<td class="details"><label for="<?php echo esc_attr( $me['id'] ) ?>"><?php echo esc_html( $me['name'] ) ?></label></td>
492
					</tr>
493
				</tbody>
494
			</table>
495
			<?php endif; ?>
496
497
			<?php if ( $pages ) : ?>
498
499
				<p><?php printf(
500
					esc_html__( 'Publicize to my %s:', 'jetpack' ),
501
					'<strong>' . esc_html__( 'Facebook Page', 'jetpack' ) . '</strong>'
502
				); ?></p>
503
				<table id="option-fb-fanpage">
504
					<tbody>
505
506
						<?php foreach ( $pages as $i => $page ) : ?>
507
							<?php if ( ! ( $i % 2 ) ) : ?>
508
								<tr>
509
							<?php endif; ?>
510
									<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>
511
									<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>
512
									<td class="details">
513
										<label for="<?php echo esc_attr( $page['id'] ) ?>">
514
											<span class="name"><?php echo esc_html( $page['name'] ) ?></span><br/>
515
											<span class="category"><?php echo esc_html( $page['category'] ) ?></span>
516
										</label>
517
									</td>
518
							<?php if ( ( $i % 2 ) || ( $i == count( $pages ) - 1 ) ): ?>
519
								</tr>
520
							<?php endif; ?>
521
						<?php endforeach; ?>
522
523
					</tbody>
524
				</table>
525
526
			<?php endif; ?>
527
528
			<?php Publicize_UI::global_checkbox( 'facebook', $_REQUEST['connection'] ); ?>
529
530
			<p style="text-align: center;">
531
				<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'] ) ?>" />
532
			</p><br/>
533
		</div>
534
535
		<?php
536
	}
537
538
	function options_save_facebook() {
539
		// Nonce check
540
		check_admin_referer( 'save_fb_token_' . $_REQUEST['connection'] );
541
542
		$id = $_POST['connection'];
543
544
		// Check for a numeric page ID
545
		$page_id = $_POST['selected_id'];
546
		if ( !ctype_digit( $page_id ) )
547
			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...
548
549
		if ( isset( $_POST['selected_id'] ) && 'profile' == $_POST['type'] ) {
550
			// Publish to User Wall/Profile
551
			$options = array(
552
				'facebook_page'       => null,
553
				'facebook_profile'    => true
554
			);
555
556
		} else {
557
			if ( 'page' != $_POST['type'] || !isset( $_POST['selected_id'] ) ) {
558
				return;
559
			}
560
561
			// Publish to Page
562
			$options = array(
563
				'facebook_page'       => $page_id,
564
				'facebook_profile'    => null
565
			);
566
		}
567
568
		Jetpack::load_xml_rpc_client();
569
		$xml = new Jetpack_IXR_Client();
570
		$xml->query( 'jetpack.setPublicizeOptions', $id, $options );
571
572
		if ( !$xml->isError() ) {
573
			$response = $xml->getResponse();
574
			Jetpack_Options::update_option( 'publicize_connections', $response );
575
		}
576
577
		$this->globalization();
578
	}
579
580
	function options_page_tumblr() {
581
		// Nonce check
582
		check_admin_referer( 'options_page_tumblr_' . $_REQUEST['connection'] );
583
584
		$connected_services = Jetpack_Options::get_option( 'publicize_connections' );
585
		$connection = $connected_services['tumblr'][$_POST['connection']];
586
		$options_to_show = $connection['connection_data']['meta']['options_responses'];
587
		$request = $options_to_show[0];
588
589
		$blogs = $request['response']['user']['blogs'];
590
591
		$blog_selected = false;
592
593
		if ( !empty( $connection['connection_data']['meta']['tumblr_base_hostname'] ) ) {
594
			foreach ( $blogs as $blog ) {
595
				if ( $connection['connection_data']['meta']['tumblr_base_hostname'] == $this->get_basehostname( $blog['url'] ) ) {
596
					$blog_selected = $connection['connection_data']['meta']['tumblr_base_hostname'];
597
					break;
598
				}
599
			}
600
601
		}
602
603
		// Use their Primary blog if they haven't selected one yet
604
		if ( !$blog_selected ) {
605
			foreach ( $blogs as $blog ) {
606
				if ( $blog['primary'] )
607
					$blog_selected = $this->get_basehostname( $blog['url'] );
608
			}
609
		} ?>
610
611
		<div id="thickbox-content">
612
613
			<?php
614
			ob_start();
615
			Publicize_UI::connected_notice( 'Tumblr' );
616
			$update_notice = ob_get_clean();
617
618
			if ( ! empty( $update_notice ) )
619
				echo $update_notice;
620
			?>
621
622
			<p><?php printf(
623
				esc_html__( 'Publicize to my %s:', 'jetpack' ),
624
				'<strong>' . esc_html__( 'Tumblr blog', 'jetpack' ) . '</strong>'
625
			); ?></p>
626
627
			<ul id="option-tumblr-blog">
628
629
			<?php
630
			foreach ( $blogs as $blog ) {
631
				$url = $this->get_basehostname( $blog['url'] ); ?>
632
				<li>
633
					<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 ); ?> />
634
					<label for="<?php echo esc_attr( $url ) ?>"><span class="name"><?php echo esc_html( $blog['title'] ) ?></span></label>
635
				</li>
636
			<?php } ?>
637
638
			</ul>
639
640
			<?php Publicize_UI::global_checkbox( 'tumblr', $_REQUEST['connection'] ); ?>
641
642
			<p style="text-align: center;">
643
				<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'] ) ?>" />
644
			</p> <br />
645
		</div>
646
647
		<?php
648
	}
649
650
	function get_basehostname( $url ) {
651
		return parse_url( $url, PHP_URL_HOST );
652
	}
653
654
	function options_save_tumblr() {
655
		// Nonce check
656
		check_admin_referer( 'save_tumblr_blog_' . $_REQUEST['connection'] );
657
658
		$id = $_POST['connection'];
659
660
		$options = array( 'tumblr_base_hostname' => $_POST['selected_id'] );
661
662
		Jetpack::load_xml_rpc_client();
663
		$xml = new Jetpack_IXR_Client();
664
		$xml->query( 'jetpack.setPublicizeOptions', $id, $options );
665
666
		if ( !$xml->isError() ) {
667
			$response = $xml->getResponse();
668
			Jetpack_Options::update_option( 'publicize_connections', $response );
669
		}
670
671
		$this->globalization();
672
	}
673
674
	function options_page_twitter() { Publicize_UI::options_page_other( 'twitter' ); }
675
	function options_page_linkedin() { Publicize_UI::options_page_other( 'linkedin' ); }
676
	function options_page_path() { Publicize_UI::options_page_other( 'path' ); }
677
	function options_page_google_plus() { Publicize_UI::options_page_other( 'google_plus' ); }
678
679
	function options_save_twitter() { $this->options_save_other( 'twitter' ); }
680
	function options_save_linkedin() { $this->options_save_other( 'linkedin' ); }
681
	function options_save_path() { $this->options_save_other( 'path' ); }
682
	function options_save_google_plus() { $this->options_save_other( 'google_plus' ); }
683
684
	function options_save_other( $service_name ) {
685
		// Nonce check
686
		check_admin_referer( 'save_' . $service_name . '_token_' . $_REQUEST['connection'] );
687
		$this->globalization();
688
	}
689
690
	/**
691
	* Already-published posts should not be Publicized by default. This filter sets checked to
692
	* false if a post has already been published.
693
	*/
694
	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...
695
		if ( 'publish' == get_post_status( $post_id ) )
696
			return false;
697
698
		return $checked;
699
	}
700
701
	/**
702
	* If there's only one shared connection to Twitter set it as twitter:site tag.
703
	*/
704
	function enhaced_twitter_cards_site_tag( $tag ) {
705
		$custom_site_tag = get_option( 'jetpack-twitter-cards-site-tag' );
706
		if( ! empty( $custom_site_tag ) )
707
			return $tag;
708
		if ( ! $this->is_enabled('twitter') )
709
			return $tag;
710
		$connections = $this->get_connections( 'twitter' );
711
		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...
712
			$connection_meta = $this->get_connection_meta( $connection );
713
			if ( 0 == $connection_meta['connection_data']['user_id'] ) {
714
				// If the connection is shared
715
				return $this->get_display_name( 'twitter', $connection );
716
			}
717
		}
718
		return $tag;
719
	}
720
721
	function save_publicized_twitter_account( $submit_post, $post_id, $service_name, $connection ) {
722
		if ( 'twitter' == $service_name && $submit_post ) {
723
			$connection_meta = $this->get_connection_meta( $connection );
724
			$publicize_twitter_user = get_post_meta( $post_id, '_publicize_twitter_user' );
725
			if ( empty( $publicize_twitter_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
726
				update_post_meta( $post_id, '_publicize_twitter_user', $this->get_display_name( 'twitter', $connection ) );
727
			}
728
		}
729
	}
730
731
	function get_publicized_twitter_account( $account, $post_id ) {
732
		if ( ! empty( $account ) ) {
733
			return $account;
734
		}
735
		$account = get_post_meta( $post_id, '_publicize_twitter_user', true );
736
		if ( ! empty( $account ) ) {
737
			return $account;
738
		}
739
		return '';
740
	}
741
742
	/**
743
	* Save the Publicized Facebook account when publishing a post
744
	* Use only Personal accounts, not Facebook Pages
745
	*/
746
	function save_publicized_facebook_account( $submit_post, $post_id, $service_name, $connection ) {
747
		$connection_meta = $this->get_connection_meta( $connection );
748
		if ( 'facebook' == $service_name && isset( $connection_meta['connection_data']['meta']['facebook_profile'] ) && $submit_post ) {
749
			$publicize_facebook_user = get_post_meta( $post_id, '_publicize_facebook_user' );
750
			if ( empty( $publicize_facebook_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
751
				$profile_link = $this->get_profile_link( 'facebook', $connection );
752
753
				if ( false !== $profile_link ) {
754
					update_post_meta( $post_id, '_publicize_facebook_user', $profile_link );
755
				}
756
			}
757
		}
758
	}
759
}
760