Completed
Push — try/seperate-publicize-handlin... ( a92583...f77f43 )
by
unknown
09:09
created

Publicize::admin_page_warning()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 32
rs 9.408
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A Publicize::disconnect() 0 3 1
A Publicize::receive_updated_publicize_connections() 0 5 1
A Publicize::register_update_publicize_connections_xmlrpc_method() 0 5 1
A Publicize::get_all_connections() 0 3 1
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( 'wp_ajax_publicize_tumblr_options_page', array( $this, 'options_page_tumblr' ) );
11
		add_action( 'wp_ajax_publicize_facebook_options_page', array( $this, 'options_page_facebook' ) );
12
		add_action( 'wp_ajax_publicize_twitter_options_page', array( $this, 'options_page_twitter' ) );
13
		add_action( 'wp_ajax_publicize_linkedin_options_page', array( $this, 'options_page_linkedin' ) );
14
		add_action( 'wp_ajax_publicize_path_options_page', array( $this, 'options_page_path' ) );
15
		add_action( 'wp_ajax_publicize_google_plus_options_page', array( $this, 'options_page_google_plus' ) );
16
17
		add_action( 'wp_ajax_publicize_tumblr_options_save', array( $this, 'options_save_tumblr' ) );
18
		add_action( 'wp_ajax_publicize_facebook_options_save', array( $this, 'options_save_facebook' ) );
19
		add_action( 'wp_ajax_publicize_twitter_options_save', array( $this, 'options_save_twitter' ) );
20
		add_action( 'wp_ajax_publicize_linkedin_options_save', array( $this, 'options_save_linkedin' ) );
21
		add_action( 'wp_ajax_publicize_path_options_save', array( $this, 'options_save_path' ) );
22
		add_action( 'wp_ajax_publicize_google_plus_options_save', array( $this, 'options_save_google_plus' ) );
23
24
		add_action( 'load-settings_page_sharing', array( $this, 'force_user_connection' ) );
25
26
		add_filter( 'publicize_checkbox_default', array( $this, 'publicize_checkbox_default' ), 10, 4 );
27
28
		add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
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
		jetpack_require_lib( 'class.jetpack-service-helper' );
42
	}
43
44
	function force_user_connection() {
45
		global $current_user;
46
		$user_token        = Jetpack_Data::get_access_token( $current_user->ID );
47
		$is_user_connected = $user_token && ! is_wp_error( $user_token );
48
49
		// If the user is already connected via Jetpack, then we're good
50
		if ( $is_user_connected ) {
51
			return;
52
		}
53
54
		// If they're not connected, then remove the Publicize UI and tell them they need to connect first
55
		global $publicize_ui;
56
		remove_action( 'pre_admin_screen_sharing', array( $publicize_ui, 'admin_page' ) );
57
58
		// Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
59
		// Jetpack::init()->admin_styles();
60
		add_action( 'pre_admin_screen_sharing', array( $publicize_ui, 'admin_page_warning' ), 1 );
61
	}
62
63
64
65
	/**
66
	 * Remove a Publicize connection
67
	 */
68
	function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) {
69
		return Jetpack_Service_Helper::disconnect( $serivce_name, $connection_id, $_blog_id, $_user_id, $force_delete );
0 ignored issues
show
Bug introduced by
The variable $serivce_name does not exist. Did you mean $service_name?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
70
	}
71
72
	function receive_updated_publicize_connections( $publicize_connections ) {
73
		Jetpack_Options::update_option( 'publicize_connections', $publicize_connections );
74
75
		return true;
76
	}
77
78
	function register_update_publicize_connections_xmlrpc_method( $methods ) {
79
		return array_merge( $methods, array(
80
			'jetpack.updatePublicizeConnections' => array( $this, 'receive_updated_publicize_connections' ),
81
		) );
82
	}
83
84
	function get_all_connections() {
85
		return Jetpack_Options::get_option( 'publicize_connections' );
86
	}
87
88
	function get_connections( $service_name, $_blog_id = false, $_user_id = false ) {
89
		$connections           = $this->get_all_connections();
90
		$connections_to_return = array();
91
		if ( ! empty( $connections ) && is_array( $connections ) ) {
92
			if ( ! empty( $connections[ $service_name ] ) ) {
93
				foreach ( $connections[ $service_name ] as $id => $connection ) {
94
					if ( 0 == $connection['connection_data']['user_id'] || $this->user_id() == $connection['connection_data']['user_id'] ) {
95
						$connections_to_return[ $id ] = $connection;
96
					}
97
				}
98
			}
99
100
			return $connections_to_return;
101
		}
102
103
		return false;
104
	}
105
106
	function get_all_connections_for_user() {
107
		$connections = $this->get_all_connections();
108
109
		$connections_to_return = array();
110
		if ( ! empty( $connections ) ) {
111
			foreach ( (array) $connections as $service_name => $connections_for_service ) {
112
				foreach ( $connections_for_service as $id => $connection ) {
113
					$user_id = intval( $connection['connection_data']['user_id'] );
114
					// phpcs:ignore WordPress.PHP.YodaConditions.NotYoda
115
					if ( $user_id === 0 || $this->user_id() === $user_id ) {
116
						$connections_to_return[ $service_name ][ $id ] = $connection;
117
					}
118
				}
119
			}
120
121
			return $connections_to_return;
122
		}
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
137
138
	function globalization() {
139
		if ( 'on' == $_REQUEST['global'] ) {
140
			$id = $_REQUEST['connection'];
141
142
			if ( ! current_user_can( $this->GLOBAL_CAP ) ) {
143
				return;
144
			}
145
146
			Jetpack::load_xml_rpc_client();
147
			$xml = new Jetpack_IXR_Client();
148
			$xml->query( 'jetpack.globalizePublicizeConnection', $id, 'globalize' );
149
150
			if ( ! $xml->isError() ) {
151
				$response = $xml->getResponse();
152
				Jetpack_Options::update_option( 'publicize_connections', $response );
153
			}
154
		}
155
	}
156
157
	function connect_url( $service_name ) {
158
		return Jetpack_Service_Helper::connect_url( $service_name );
159
	}
160
161
	function refresh_url( $service_name ) {
162
		return Jetpack_Service_Helper::refresh_url( $service_name );
163
	}
164
165
	function disconnect_url( $service_name, $id ) {
166
		return Jetpack_Service_Helper::disconnect_url( $service_name, $id );
167
	}
168
169
	/**
170
	 * Get social networks, either all available or only those that the site is connected to.
171
	 *
172
	 * @since 2.0
173
	 *
174
	 * @param string $filter Select the list of services that will be returned. Defaults to 'all', accepts 'connected'.
175
	 *
176
	 * @return array List of social networks.
177
	 */
178
	function get_services( $filter = 'all' ) {
179
		$services = array(
180
			'facebook'    => array(),
181
			'twitter'     => array(),
182
			'linkedin'    => array(),
183
			'tumblr'      => array(),
184
			'path'        => array(),
185
			'google_plus' => array(),
186
		);
187
188
		if ( 'all' == $filter ) {
189
			return $services;
190
		} else {
191
			$connected_services = array();
192
			foreach ( $services as $service => $empty ) {
193
				$connections = $this->get_connections( $service );
194
				if ( $connections ) {
195
					$connected_services[ $service ] = $connections;
196
				}
197
			}
198
			return $connected_services;
199
		}
200
	}
201
202
	function get_connection( $service, $id, $_blog_id = false, $_user_id = false ) {
203
		// Stub
204
	}
205
206
	function flag_post_for_publicize( $new_status, $old_status, $post ) {
207
		if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) {
208
			return;
209
		}
210
211
		if ( 'publish' == $new_status && 'publish' != $old_status ) {
212
			/**
213
			 * Determines whether a post being published gets publicized.
214
			 *
215
			 * Side-note: Possibly our most alliterative filter name.
216
			 *
217
			 * @module publicize
218
			 *
219
			 * @since 4.1.0
220
			 *
221
			 * @param bool $should_publicize Should the post be publicized? Default to true.
222
			 * @param WP_POST $post Current Post object.
223
			 */
224
			$should_publicize = apply_filters( 'publicize_should_publicize_published_post', true, $post );
225
226
			if ( $should_publicize ) {
227
				update_post_meta( $post->ID, $this->PENDING, true );
228
			}
229
		}
230
	}
231
232
	function test_connection( $service_name, $connection ) {
233
234
		$id = $this->get_connection_id( $connection );
235
236
		Jetpack::load_xml_rpc_client();
237
		$xml = new Jetpack_IXR_Client();
238
		$xml->query( 'jetpack.testPublicizeConnection', $id );
239
240
		// Bail if all is well
241
		if ( ! $xml->isError() ) {
242
			return true;
243
		}
244
245
		$xml_response            = $xml->getResponse();
246
		$connection_test_message = $xml_response['faultString'];
247
248
		// Set up refresh if the user can
249
		$user_can_refresh = current_user_can( $this->GLOBAL_CAP );
250
		if ( $user_can_refresh ) {
251
			$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...
252
			$refresh_text = sprintf( _x( 'Refresh connection with %s', 'Refresh connection with {social media service}', 'jetpack' ), $this->get_service_label( $service_name ) );
253
			$refresh_url  = $this->refresh_url( $service_name );
254
		}
255
256
		$error_data = array(
257
			'user_can_refresh' => $user_can_refresh,
258
			'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...
259
			'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...
260
		);
261
262
		return new WP_Error( 'pub_conn_test_failed', $connection_test_message, $error_data );
263
	}
264
265
	/**
266
	 * Save a flag locally to indicate that this post has already been Publicized via the selected
267
	 * connections.
268
	 */
269
	function save_publicized( $post_ID, $post = null, $update = null ) {
270
		if ( is_null( $post ) ) {
271
			return;
272
		}
273
		// Only do this when a post transitions to being published
274
		if ( get_post_meta( $post->ID, $this->PENDING ) && $this->post_type_is_publicizeable( $post->post_type ) ) {
275
			$connected_services = $this->get_all_connections();
276
			if ( ! empty( $connected_services ) ) {
277
				/**
278
				 * Fires when a post is saved that has is marked as pending publicizing
279
				 *
280
				 * @since 4.1.0
281
				 *
282
				 * @param int The post ID
283
				 */
284
				do_action_deprecated( 'jetpack_publicize_post', $post->ID, '4.8.0', 'jetpack_published_post_flags' );
285
			}
286
			delete_post_meta( $post->ID, $this->PENDING );
287
			update_post_meta( $post->ID, $this->POST_DONE . 'all', true );
288
		}
289
	}
290
291
	function set_post_flags( $flags, $post ) {
292
		$flags['publicize_post'] = false;
293
		if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) {
294
			return $flags;
295
		}
296
		/** This filter is already documented in modules/publicize/publicize-jetpack.php */
297
		if ( ! apply_filters( 'publicize_should_publicize_published_post', true, $post ) ) {
298
			return $flags;
299
		}
300
301
		$connected_services = $this->get_all_connections();
302
303
		if ( empty( $connected_services ) ) {
304
			return $flags;
305
		}
306
307
		$flags['publicize_post'] = true;
308
309
		return $flags;
310
	}
311
312
	/**
313
	 * Options Code
314
	 */
315
316
	function options_page_facebook() {
317
		$connected_services = $this->get_all_connections();
318
		$connection         = $connected_services['facebook'][ $_REQUEST['connection'] ];
319
		$options_to_show    = ( ! empty( $connection['connection_data']['meta']['options_responses'] ) ? $connection['connection_data']['meta']['options_responses'] : false );
320
321
		// Nonce check
322
		check_admin_referer( 'options_page_facebook_' . $_REQUEST['connection'] );
323
324
		$pages = ( ! empty( $options_to_show[1]['data'] ) ? $options_to_show[1]['data'] : false );
325
326
		$page_selected   = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
327
		if ( ! empty( $connection['connection_data']['meta']['facebook_page'] ) ) {
328
			$found = false;
329
			if ( $pages && isset( $pages->data ) && is_array( $pages->data )  ) {
330
				foreach ( $pages->data as $page ) {
331
					if ( $page->id == $connection['connection_data']['meta']['facebook_page'] ) {
332
						$found = true;
333
						break;
334
					}
335
				}
336
			}
337
338
			if ( $found ) {
339
				$page_selected   = $connection['connection_data']['meta']['facebook_page'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
340
			}
341
		}
342
343
		?>
344
345
		<div id="thickbox-content">
346
347
			<?php
348
			ob_start();
349
			Publicize_UI::connected_notice( 'Facebook' );
350
			$update_notice = ob_get_clean();
351
352
			if ( ! empty( $update_notice ) ) {
353
				echo $update_notice;
354
			}
355
			$page_info_message = sprintf(
356
				__( 'Facebook supports Publicize connections to Facebook Pages, but not to Facebook Profiles. <a href="%s">Learn More about Publicize for Facebook</a>', 'jetpack' ),
357
				'https://jetpack.com/support/publicize/facebook'
358
			);
359
360
			if ( $pages ) : ?>
361
				<p><?php _e( 'Publicize to my <strong>Facebook Page</strong>:', 'jetpack' ); ?></p>
362
				<table id="option-fb-fanpage">
363
					<tbody>
364
365
					<?php foreach ( $pages as $i => $page ) : ?>
366
						<?php if ( ! ( $i % 2 ) ) : ?>
367
							<tr>
368
						<?php endif; ?>
369
						<td class="radio"><input type="radio" name="option" data-type="page"
370
						                         id="<?php echo esc_attr( $page['id'] ) ?>"
371
						                         value="<?php echo esc_attr( $page['id'] ) ?>" <?php checked( $page_selected && $page_selected == $page['id'], true ); ?> />
372
						</td>
373
						<td class="thumbnail"><label for="<?php echo esc_attr( $page['id'] ) ?>"><img
374
									src="<?php echo esc_url( str_replace( '_s', '_q', $page['picture']['data']['url'] ) ) ?>"
375
									width="50" height="50"/></label></td>
376
						<td class="details">
377
							<label for="<?php echo esc_attr( $page['id'] ) ?>">
378
								<span class="name"><?php echo esc_html( $page['name'] ) ?></span><br/>
379
								<span class="category"><?php echo esc_html( $page['category'] ) ?></span>
380
							</label>
381
						</td>
382
						<?php if ( ( $i % 2 ) || ( $i == count( $pages ) - 1 ) ): ?>
383
							</tr>
384
						<?php endif; ?>
385
					<?php endforeach; ?>
386
387
					</tbody>
388
				</table>
389
390
				<?php Publicize_UI::global_checkbox( 'facebook', $_REQUEST['connection'] ); ?>
391
				<p style="text-align: center;">
392
					<input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>"
393
					       class="button fb-options save-options" name="save"
394
					       data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>"
395
					       rel="<?php echo wp_create_nonce( 'save_fb_token_' . $_REQUEST['connection'] ) ?>"/>
396
				</p><br/>
397
				<p><?php echo $page_info_message; ?></p>
398
			<?php else: ?>
399
				<div>
400
					<p><?php echo $page_info_message; ?></p>
401
					<p><?php printf( __( '<a class="button" href="%s" target="%s">Create a Facebook page</a> to get started.', 'jetpack' ), 'https://www.facebook.com/pages/creation/', '_blank noopener noreferrer' ); ?></p>
402
				</div>
403
			<?php endif; ?>
404
		</div>
405
		<?php
406
	}
407
408
	function options_save_facebook() {
409
		// Nonce check
410
		check_admin_referer( 'save_fb_token_' . $_REQUEST['connection'] );
411
412
		// Check for a numeric page ID
413
		$page_id = $_POST['selected_id'];
414
		if ( ! ctype_digit( $page_id ) ) {
415
			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...
416
		}
417
418
		if ( 'page' != $_POST['type'] || ! isset( $_POST['selected_id'] ) ) {
419
			return;
420
		}
421
422
		// Publish to Page
423
		$options = array(
424
			'facebook_page'    => $page_id,
425
			'facebook_profile' => null
426
		);
427
428
		$this->set_remote_publicize_options( $_POST['connection'], $options );
429
	}
430
431
	function options_page_tumblr() {
432
		// Nonce check
433
		check_admin_referer( 'options_page_tumblr_' . $_REQUEST['connection'] );
434
435
		$connected_services = $this->get_all_connections();
436
		$connection         = $connected_services['tumblr'][ $_POST['connection'] ];
437
		$options_to_show    = $connection['connection_data']['meta']['options_responses'];
438
		$request            = $options_to_show[0];
439
440
		$blogs = $request['response']['user']['blogs'];
441
442
		$blog_selected = false;
443
444
		if ( ! empty( $connection['connection_data']['meta']['tumblr_base_hostname'] ) ) {
445
			foreach ( $blogs as $blog ) {
446
				if ( $connection['connection_data']['meta']['tumblr_base_hostname'] == $this->get_basehostname( $blog['url'] ) ) {
447
					$blog_selected = $connection['connection_data']['meta']['tumblr_base_hostname'];
448
					break;
449
				}
450
			}
451
452
		}
453
454
		// Use their Primary blog if they haven't selected one yet
455
		if ( ! $blog_selected ) {
456
			foreach ( $blogs as $blog ) {
457
				if ( $blog['primary'] ) {
458
					$blog_selected = $this->get_basehostname( $blog['url'] );
459
				}
460
			}
461
		} ?>
462
463
		<div id="thickbox-content">
464
465
			<?php
466
			ob_start();
467
			Publicize_UI::connected_notice( 'Tumblr' );
468
			$update_notice = ob_get_clean();
469
470
			if ( ! empty( $update_notice ) ) {
471
				echo $update_notice;
472
			}
473
			?>
474
475
			<p><?php _e( 'Publicize to my <strong>Tumblr blog</strong>:', 'jetpack' ); ?></p>
476
477
			<ul id="option-tumblr-blog">
478
479
				<?php
480
				foreach ( $blogs as $blog ) {
481
					$url = $this->get_basehostname( $blog['url'] ); ?>
482
					<li>
483
						<input type="radio" name="option" data-type="blog" id="<?php echo esc_attr( $url ) ?>"
484
						       value="<?php echo esc_attr( $url ) ?>" <?php checked( $blog_selected == $url, true ); ?> />
485
						<label for="<?php echo esc_attr( $url ) ?>"><span
486
								class="name"><?php echo esc_html( $blog['title'] ) ?></span></label>
487
					</li>
488
				<?php } ?>
489
490
			</ul>
491
492
			<?php Publicize_UI::global_checkbox( 'tumblr', $_REQUEST['connection'] ); ?>
493
494
			<p style="text-align: center;">
495
				<input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>"
496
				       class="button tumblr-options save-options" name="save"
497
				       data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>"
498
				       rel="<?php echo wp_create_nonce( 'save_tumblr_blog_' . $_REQUEST['connection'] ) ?>"/>
499
			</p> <br/>
500
		</div>
501
502
		<?php
503
	}
504
505
	function get_basehostname( $url ) {
506
		return parse_url( $url, PHP_URL_HOST );
507
	}
508
509
	function options_save_tumblr() {
510
		// Nonce check
511
		check_admin_referer( 'save_tumblr_blog_' . $_REQUEST['connection'] );
512
		$options = array( 'tumblr_base_hostname' => $_POST['selected_id'] );
513
514
		$this->set_remote_publicize_options( $_POST['connection'], $options );
515
516
	}
517
518
	function set_remote_publicize_options( $id, $options ) {
519
		Jetpack::load_xml_rpc_client();
520
		$xml = new Jetpack_IXR_Client();
521
		$xml->query( 'jetpack.setPublicizeOptions', $id, $options );
522
523
		if ( ! $xml->isError() ) {
524
			$response = $xml->getResponse();
525
			Jetpack_Options::update_option( 'publicize_connections', $response );
526
			$this->globalization();
527
		}
528
	}
529
530
	function options_page_twitter() {
531
		Publicize_UI::options_page_other( 'twitter' );
532
	}
533
534
	function options_page_linkedin() {
535
		Publicize_UI::options_page_other( 'linkedin' );
536
	}
537
538
	function options_page_path() {
539
		Publicize_UI::options_page_other( 'path' );
540
	}
541
542
	function options_page_google_plus() {
543
		Publicize_UI::options_page_other( 'google_plus' );
544
	}
545
546
	function options_save_twitter() {
547
		$this->options_save_other( 'twitter' );
548
	}
549
550
	function options_save_linkedin() {
551
		$this->options_save_other( 'linkedin' );
552
	}
553
554
	function options_save_path() {
555
		$this->options_save_other( 'path' );
556
	}
557
558
	function options_save_google_plus() {
559
		$this->options_save_other( 'google_plus' );
560
	}
561
562
	function options_save_other( $service_name ) {
563
		// Nonce check
564
		check_admin_referer( 'save_' . $service_name . '_token_' . $_REQUEST['connection'] );
565
		$this->globalization();
566
	}
567
568
	/**
569
	 * Already-published posts should not be Publicized by default. This filter sets checked to
570
	 * false if a post has already been published.
571
	 */
572
	function publicize_checkbox_default( $checked, $post_id, $name, $connection ) {
573
		if ( 'publish' == get_post_status( $post_id ) ) {
574
			return false;
575
		}
576
577
		return $checked;
578
	}
579
580
	/**
581
	 * If there's only one shared connection to Twitter set it as twitter:site tag.
582
	 */
583
	function enhaced_twitter_cards_site_tag( $tag ) {
584
		$custom_site_tag = get_option( 'jetpack-twitter-cards-site-tag' );
585
		if ( ! empty( $custom_site_tag ) ) {
586
			return $tag;
587
		}
588
		if ( ! $this->is_enabled( 'twitter' ) ) {
589
			return $tag;
590
		}
591
		$connections = $this->get_connections( 'twitter' );
592
		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...
593
			$connection_meta = $this->get_connection_meta( $connection );
594
			if ( 0 == $connection_meta['connection_data']['user_id'] ) {
595
				// If the connection is shared
596
				return $this->get_display_name( 'twitter', $connection );
597
			}
598
		}
599
600
		return $tag;
601
	}
602
603
	function save_publicized_twitter_account( $submit_post, $post_id, $service_name, $connection ) {
604
		if ( 'twitter' == $service_name && $submit_post ) {
605
			$connection_meta        = $this->get_connection_meta( $connection );
606
			$publicize_twitter_user = get_post_meta( $post_id, '_publicize_twitter_user' );
607
			if ( empty( $publicize_twitter_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
608
				update_post_meta( $post_id, '_publicize_twitter_user', $this->get_display_name( 'twitter', $connection ) );
609
			}
610
		}
611
	}
612
613
	function get_publicized_twitter_account( $account, $post_id ) {
614
		if ( ! empty( $account ) ) {
615
			return $account;
616
		}
617
		$account = get_post_meta( $post_id, '_publicize_twitter_user', true );
618
		if ( ! empty( $account ) ) {
619
			return $account;
620
		}
621
622
		return '';
623
	}
624
625
	/**
626
	 * Save the Publicized Facebook account when publishing a post
627
	 * Use only Personal accounts, not Facebook Pages
628
	 */
629
	function save_publicized_facebook_account( $submit_post, $post_id, $service_name, $connection ) {
630
		$connection_meta = $this->get_connection_meta( $connection );
631
		if ( 'facebook' == $service_name && isset( $connection_meta['connection_data']['meta']['facebook_profile'] ) && $submit_post ) {
632
			$publicize_facebook_user = get_post_meta( $post_id, '_publicize_facebook_user' );
633
			if ( empty( $publicize_facebook_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
634
				$profile_link = $this->get_profile_link( 'facebook', $connection );
635
636
				if ( false !== $profile_link ) {
637
					update_post_meta( $post_id, '_publicize_facebook_user', $profile_link );
638
				}
639
			}
640
		}
641
	}
642
}
643