PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.4
Jetpack – WP Security, Backup, Speed, & Growth v6.4
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / publicize / publicize-jetpack.php
publicize-jetpack.php
859 lines 28.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
31
32 add_action( 'wp_insert_post', array( $this, 'save_publicized' ), 11, 3 );
33
34 add_filter( 'jetpack_twitter_cards_site_tag', array( $this, 'enhaced_twitter_cards_site_tag' ) );
35
36 add_action( 'publicize_save_meta', array( $this, 'save_publicized_twitter_account' ), 10, 4 );
37 add_action( 'publicize_save_meta', array( $this, 'save_publicized_facebook_account' ), 10, 4 );
38
39 add_filter( 'jetpack_sharing_twitter_via', array( $this, 'get_publicized_twitter_account' ), 10, 2 );
40
41 include_once( JETPACK__PLUGIN_DIR . 'modules/publicize/enhanced-open-graph.php' );
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( $this, 'admin_page_warning' ), 1 );
61 }
62
63 function admin_page_warning() {
64 $jetpack = Jetpack::init();
65 $blog_name = get_bloginfo( 'blogname' );
66 if ( empty( $blog_name ) ) {
67 $blog_name = home_url( '/' );
68 }
69
70 ?>
71 <div id="message" class="updated jetpack-message jp-connect">
72 <div class="jetpack-wrap-container">
73 <div class="jetpack-text-container">
74 <p><?php printf(
75 /* translators: %s is the name of the blog */
76 esc_html( wptexturize( __( "To use Publicize, you'll need to link your %s account to your WordPress.com account using the link below.", 'jetpack' ) ) ),
77 '<strong>' . esc_html( $blog_name ) . '</strong>'
78 ); ?></p>
79 <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>
80 </div>
81 <div class="jetpack-install-container">
82 <p class="submit"><a
83 href="<?php echo $jetpack->build_connect_url( false, menu_page_url( 'sharing', false ) ); ?>"
84 class="button-connector"
85 id="wpcom-connect"><?php esc_html_e( 'Link account with WordPress.com', 'jetpack' ); ?></a>
86 </p>
87 <p class="jetpack-install-blurb">
88 <?php jetpack_render_tos_blurb(); ?>
89 </p>
90 </div>
91 </div>
92 </div>
93 <?php
94 }
95
96 /**
97 * Remove a Publicize connection
98 */
99 function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) {
100 Jetpack::load_xml_rpc_client();
101 $xml = new Jetpack_IXR_Client();
102 $xml->query( 'jetpack.deletePublicizeConnection', $connection_id );
103
104 if ( ! $xml->isError() ) {
105 Jetpack_Options::update_option( 'publicize_connections', $xml->getResponse() );
106 } else {
107 return false;
108 }
109 }
110
111 function receive_updated_publicize_connections( $publicize_connections ) {
112 Jetpack_Options::update_option( 'publicize_connections', $publicize_connections );
113
114 return true;
115 }
116
117 function register_update_publicize_connections_xmlrpc_method( $methods ) {
118 return array_merge( $methods, array(
119 'jetpack.updatePublicizeConnections' => array( $this, 'receive_updated_publicize_connections' ),
120 ) );
121 }
122
123 function get_all_connections() {
124 return Jetpack_Options::get_option( 'publicize_connections' );
125 }
126
127 function get_connections( $service_name, $_blog_id = false, $_user_id = false ) {
128 $connections = $this->get_all_connections();
129 $connections_to_return = array();
130 if ( ! empty( $connections ) && is_array( $connections ) ) {
131 if ( ! empty( $connections[ $service_name ] ) ) {
132 foreach ( $connections[ $service_name ] as $id => $connection ) {
133 if ( 0 == $connection['connection_data']['user_id'] || $this->user_id() == $connection['connection_data']['user_id'] ) {
134 $connections_to_return[ $id ] = $connection;
135 }
136 }
137 }
138
139 return $connections_to_return;
140 }
141
142 return false;
143 }
144
145 function get_all_connections_for_user() {
146 $connections = $this->get_all_connections();
147
148 $connections_to_return = array();
149 if ( ! empty( $connections ) ) {
150 foreach ( (array) $connections as $service_name => $connections_for_service ) {
151 foreach ( $connections_for_service as $id => $connection ) {
152 $user_id = intval( $connection['connection_data']['user_id'] );
153 // phpcs:ignore WordPress.PHP.YodaConditions.NotYoda
154 if ( $user_id === 0 || $this->user_id() === $user_id ) {
155 $connections_to_return[ $service_name ][ $id ] = $connection;
156 }
157 }
158 }
159
160 return $connections_to_return;
161 }
162
163 return false;
164 }
165
166 function get_connection_id( $connection ) {
167 return $connection['connection_data']['id'];
168 }
169
170 function get_connection_meta( $connection ) {
171 $connection['user_id'] = $connection['connection_data']['user_id']; // Allows for shared connections
172 return $connection;
173 }
174
175 function admin_page_load() {
176 if ( isset( $_GET['action'] ) ) {
177 if ( isset( $_GET['service'] ) ) {
178 $service_name = $_GET['service'];
179 }
180
181 switch ( $_GET['action'] ) {
182 case 'error':
183 add_action( 'pre_admin_screen_sharing', array( $this, 'display_connection_error' ), 9 );
184 break;
185
186 case 'request':
187 check_admin_referer( 'keyring-request', 'kr_nonce' );
188 check_admin_referer( "keyring-request-$service_name", 'nonce' );
189
190 $verification = Jetpack::generate_secrets( 'publicize' );
191 if ( ! $verification ) {
192 $url = Jetpack::admin_url( 'jetpack#/settings' );
193 wp_die( sprintf( __( "Jetpack is not connected. Please connect Jetpack by visiting <a href='%s'>Settings</a>.", 'jetpack' ), $url ) );
194
195 }
196 $stats_options = get_option( 'stats_options' );
197 $wpcom_blog_id = Jetpack_Options::get_option( 'id' );
198 $wpcom_blog_id = ! empty( $wpcom_blog_id ) ? $wpcom_blog_id : $stats_options['blog_id'];
199
200 $user = wp_get_current_user();
201 $redirect = $this->api_url( $service_name, urlencode_deep( array(
202 'action' => 'request',
203 'redirect_uri' => add_query_arg( array( 'action' => 'done' ), menu_page_url( 'sharing', false ) ),
204 'for' => 'publicize',
205 // required flag that says this connection is intended for publicize
206 'siteurl' => site_url(),
207 'state' => $user->ID,
208 'blog_id' => $wpcom_blog_id,
209 'secret_1' => $verification['secret_1'],
210 'secret_2' => $verification['secret_2'],
211 'eol' => $verification['exp'],
212 ) ) );
213 wp_redirect( $redirect );
214 exit;
215 break;
216
217 case 'completed':
218 Jetpack::load_xml_rpc_client();
219 $xml = new Jetpack_IXR_Client();
220 $xml->query( 'jetpack.fetchPublicizeConnections' );
221
222 if ( ! $xml->isError() ) {
223 $response = $xml->getResponse();
224 Jetpack_Options::update_option( 'publicize_connections', $response );
225 }
226
227 break;
228
229 case 'delete':
230 $id = $_GET['id'];
231
232 check_admin_referer( 'keyring-request', 'kr_nonce' );
233 check_admin_referer( "keyring-request-$service_name", 'nonce' );
234
235 $this->disconnect( $service_name, $id );
236
237 add_action( 'admin_notices', array( $this, 'display_disconnected' ) );
238 break;
239 }
240 }
241
242 // Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
243 // Errors encountered on WordPress.com's end are passed back as a code
244 /*
245 if ( isset( $_GET['action'] ) && 'error' == $_GET['action'] ) {
246 // Load Jetpack's styles to handle the box
247 Jetpack::init()->admin_styles();
248 }
249 */
250 }
251
252 function display_connection_error() {
253 $code = false;
254 if ( isset( $_GET['service'] ) ) {
255 $service_name = $_GET['service'];
256 $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 ) );
257 } else {
258 if ( isset( $_GET['publicize_error'] ) ) {
259 $code = strtolower( $_GET['publicize_error'] );
260 switch ( $code ) {
261 case '400':
262 $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' );
263 break;
264 case 'secret_mismatch':
265 $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' );
266 break;
267 case 'empty_blog_id':
268 $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' );
269 break;
270 case 'empty_state':
271 $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() );
272 break;
273 default:
274 $error = __( 'Something which should never happen, happened. Sorry about that. If you try again, maybe it will work.', 'jetpack' );
275 break;
276 }
277 } else {
278 $error = __( 'There was a problem connecting with Publicize. Please try again in a moment.', 'jetpack' );
279 }
280 }
281 // Using the same formatting/style as Jetpack::admin_notices() error
282 ?>
283 <div id="message" class="jetpack-message jetpack-err">
284 <div class="squeezer">
285 <h2><?php echo wp_kses( $error, array( 'a' => array( 'href' => true ),
286 'code' => true,
287 'strong' => true,
288 'br' => true,
289 'b' => true
290 ) ); ?></h2>
291 <?php if ( $code ) : ?>
292 <p><?php printf( __( 'Error code: %s', 'jetpack' ), esc_html( stripslashes( $code ) ) ); ?></p>
293 <?php endif; ?>
294 </div>
295 </div>
296 <?php
297 }
298
299 function display_disconnected() {
300 echo "<div class='updated'>\n";
301 echo '<p>' . esc_html( __( 'That connection has been removed.', 'jetpack' ) ) . "</p>\n";
302 echo "</div>\n\n";
303 }
304
305 function globalization() {
306 if ( 'on' == $_REQUEST['global'] ) {
307 $id = $_REQUEST['connection'];
308
309 if ( ! current_user_can( $this->GLOBAL_CAP ) ) {
310 return;
311 }
312
313 Jetpack::load_xml_rpc_client();
314 $xml = new Jetpack_IXR_Client();
315 $xml->query( 'jetpack.globalizePublicizeConnection', $id, 'globalize' );
316
317 if ( ! $xml->isError() ) {
318 $response = $xml->getResponse();
319 Jetpack_Options::update_option( 'publicize_connections', $response );
320 }
321 }
322 }
323
324 /**
325 * Gets a URL to the public-api actions. Works like WP's admin_url
326 *
327 * @param string $service Shortname of a specific service.
328 *
329 * @return URL to specific public-api process
330 */
331 // on WordPress.com this is/calls Keyring::admin_url
332 function api_url( $service = false, $params = array() ) {
333 /**
334 * Filters the API URL used to interact with WordPress.com.
335 *
336 * @module publicize
337 *
338 * @since 2.0.0
339 *
340 * @param string https://public-api.wordpress.com/connect/?jetpack=publicize Default Publicize API URL.
341 */
342 $url = apply_filters( 'publicize_api_url', 'https://public-api.wordpress.com/connect/?jetpack=publicize' );
343
344 if ( $service ) {
345 $url = add_query_arg( array( 'service' => $service ), $url );
346 }
347
348 if ( count( $params ) ) {
349 $url = add_query_arg( $params, $url );
350 }
351
352 return $url;
353 }
354
355 function connect_url( $service_name ) {
356 return add_query_arg( array(
357 'action' => 'request',
358 'service' => $service_name,
359 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
360 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
361 ), menu_page_url( 'sharing', false ) );
362 }
363
364 function refresh_url( $service_name ) {
365 return add_query_arg( array(
366 'action' => 'request',
367 'service' => $service_name,
368 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
369 'refresh' => 1,
370 'for' => 'publicize',
371 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
372 ), admin_url( 'options-general.php?page=sharing' ) );
373 }
374
375 function disconnect_url( $service_name, $id ) {
376 return add_query_arg( array(
377 'action' => 'delete',
378 'service' => $service_name,
379 'id' => $id,
380 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
381 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
382 ), menu_page_url( 'sharing', false ) );
383 }
384
385 /**
386 * Get social networks, either all available or only those that the site is connected to.
387 *
388 * @since 2.0
389 *
390 * @param string $filter Select the list of services that will be returned. Defaults to 'all', accepts 'connected'.
391 *
392 * @return array List of social networks.
393 */
394 function get_services( $filter = 'all' ) {
395 $services = array(
396 'facebook' => array(),
397 'twitter' => array(),
398 'linkedin' => array(),
399 'tumblr' => array(),
400 'path' => array(),
401 'google_plus' => array(),
402 );
403
404 if ( 'all' == $filter ) {
405 return $services;
406 } else {
407 $connected_services = array();
408 foreach ( $services as $service => $empty ) {
409 $connections = $this->get_connections( $service );
410 if ( $connections ) {
411 $connected_services[ $service ] = $connections;
412 }
413 }
414 return $connected_services;
415 }
416 }
417
418 function get_connection( $service, $id, $_blog_id = false, $_user_id = false ) {
419 // Stub
420 }
421
422 function flag_post_for_publicize( $new_status, $old_status, $post ) {
423 if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) {
424 return;
425 }
426
427 if ( 'publish' == $new_status && 'publish' != $old_status ) {
428 /**
429 * Determines whether a post being published gets publicized.
430 *
431 * Side-note: Possibly our most alliterative filter name.
432 *
433 * @module publicize
434 *
435 * @since 4.1.0
436 *
437 * @param bool $should_publicize Should the post be publicized? Default to true.
438 * @param WP_POST $post Current Post object.
439 */
440 $should_publicize = apply_filters( 'publicize_should_publicize_published_post', true, $post );
441
442 if ( $should_publicize ) {
443 update_post_meta( $post->ID, $this->PENDING, true );
444 }
445 }
446 }
447
448 function test_connection( $service_name, $connection ) {
449
450 $id = $this->get_connection_id( $connection );
451
452 Jetpack::load_xml_rpc_client();
453 $xml = new Jetpack_IXR_Client();
454 $xml->query( 'jetpack.testPublicizeConnection', $id );
455
456 // Bail if all is well
457 if ( ! $xml->isError() ) {
458 return true;
459 }
460
461 $xml_response = $xml->getResponse();
462 $connection_test_message = $xml_response['faultString'];
463
464 // Set up refresh if the user can
465 $user_can_refresh = current_user_can( $this->GLOBAL_CAP );
466 if ( $user_can_refresh ) {
467 $nonce = wp_create_nonce( "keyring-request-" . $service_name );
468 $refresh_text = sprintf( _x( 'Refresh connection with %s', 'Refresh connection with {social media service}', 'jetpack' ), $this->get_service_label( $service_name ) );
469 $refresh_url = $this->refresh_url( $service_name );
470 }
471
472 $error_data = array(
473 'user_can_refresh' => $user_can_refresh,
474 'refresh_text' => $refresh_text,
475 'refresh_url' => $refresh_url
476 );
477
478 return new WP_Error( 'pub_conn_test_failed', $connection_test_message, $error_data );
479 }
480
481 /**
482 * Save a flag locally to indicate that this post has already been Publicized via the selected
483 * connections.
484 */
485 function save_publicized( $post_ID, $post = null, $update = null ) {
486 if ( is_null( $post ) ) {
487 return;
488 }
489 // Only do this when a post transitions to being published
490 if ( get_post_meta( $post->ID, $this->PENDING ) && $this->post_type_is_publicizeable( $post->post_type ) ) {
491 $connected_services = $this->get_all_connections();
492 if ( ! empty( $connected_services ) ) {
493 /**
494 * Fires when a post is saved that has is marked as pending publicizing
495 *
496 * @since 4.1.0
497 *
498 * @param int The post ID
499 */
500 do_action_deprecated( 'jetpack_publicize_post', $post->ID, '4.8.0', 'jetpack_published_post_flags' );
501 }
502 delete_post_meta( $post->ID, $this->PENDING );
503 update_post_meta( $post->ID, $this->POST_DONE . 'all', true );
504 }
505 }
506
507 function set_post_flags( $flags, $post ) {
508 $flags['publicize_post'] = false;
509 if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) {
510 return $flags;
511 }
512 /** This filter is already documented in modules/publicize/publicize-jetpack.php */
513 if ( ! apply_filters( 'publicize_should_publicize_published_post', true, $post ) ) {
514 return $flags;
515 }
516
517 $connected_services = $this->get_all_connections();
518
519 if ( empty( $connected_services ) ) {
520 return $flags;
521 }
522
523 $flags['publicize_post'] = true;
524
525 return $flags;
526 }
527
528 /**
529 * Options Code
530 */
531
532 function options_page_facebook() {
533 $connected_services = $this->get_all_connections();
534 $connection = $connected_services['facebook'][ $_REQUEST['connection'] ];
535 $options_to_show = ( ! empty( $connection['connection_data']['meta']['options_responses'] ) ? $connection['connection_data']['meta']['options_responses'] : false );
536
537 // Nonce check
538 check_admin_referer( 'options_page_facebook_' . $_REQUEST['connection'] );
539
540 $pages = ( ! empty( $options_to_show[1]['data'] ) ? $options_to_show[1]['data'] : false );
541
542 $page_selected = false;
543 if ( ! empty( $connection['connection_data']['meta']['facebook_page'] ) ) {
544 $found = false;
545 if ( $pages && isset( $pages->data ) && is_array( $pages->data ) ) {
546 foreach ( $pages->data as $page ) {
547 if ( $page->id == $connection['connection_data']['meta']['facebook_page'] ) {
548 $found = true;
549 break;
550 }
551 }
552 }
553
554 if ( $found ) {
555 $page_selected = $connection['connection_data']['meta']['facebook_page'];
556 }
557 }
558
559 ?>
560
561 <div id="thickbox-content">
562
563 <?php
564 ob_start();
565 Publicize_UI::connected_notice( 'Facebook' );
566 $update_notice = ob_get_clean();
567
568 if ( ! empty( $update_notice ) ) {
569 echo $update_notice;
570 }
571 $page_info_message = sprintf(
572 __( 'Facebook supports Publicize connections to Facebook Pages, but not to Facebook Profiles. <a href="%s">Learn More about Publicize for Facebook</a>', 'jetpack' ),
573 'https://jetpack.com/support/publicize/facebook'
574 );
575
576 if ( $pages ) : ?>
577 <p><?php _e( 'Publicize to my <strong>Facebook Page</strong>:', 'jetpack' ); ?></p>
578 <table id="option-fb-fanpage">
579 <tbody>
580
581 <?php foreach ( $pages as $i => $page ) : ?>
582 <?php if ( ! ( $i % 2 ) ) : ?>
583 <tr>
584 <?php endif; ?>
585 <td class="radio"><input type="radio" name="option" data-type="page"
586 id="<?php echo esc_attr( $page['id'] ) ?>"
587 value="<?php echo esc_attr( $page['id'] ) ?>" <?php checked( $page_selected && $page_selected == $page['id'], true ); ?> />
588 </td>
589 <td class="thumbnail"><label for="<?php echo esc_attr( $page['id'] ) ?>"><img
590 src="<?php echo esc_url( str_replace( '_s', '_q', $page['picture']['data']['url'] ) ) ?>"
591 width="50" height="50"/></label></td>
592 <td class="details">
593 <label for="<?php echo esc_attr( $page['id'] ) ?>">
594 <span class="name"><?php echo esc_html( $page['name'] ) ?></span><br/>
595 <span class="category"><?php echo esc_html( $page['category'] ) ?></span>
596 </label>
597 </td>
598 <?php if ( ( $i % 2 ) || ( $i == count( $pages ) - 1 ) ): ?>
599 </tr>
600 <?php endif; ?>
601 <?php endforeach; ?>
602
603 </tbody>
604 </table>
605
606 <?php Publicize_UI::global_checkbox( 'facebook', $_REQUEST['connection'] ); ?>
607 <p style="text-align: center;">
608 <input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>"
609 class="button fb-options save-options" name="save"
610 data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>"
611 rel="<?php echo wp_create_nonce( 'save_fb_token_' . $_REQUEST['connection'] ) ?>"/>
612 </p><br/>
613 <p><?php echo $page_info_message; ?></p>
614 <?php else: ?>
615 <div>
616 <p><?php echo $page_info_message; ?></p>
617 <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>
618 </div>
619 <?php endif; ?>
620 </div>
621 <?php
622 }
623
624 function options_save_facebook() {
625 // Nonce check
626 check_admin_referer( 'save_fb_token_' . $_REQUEST['connection'] );
627
628 // Check for a numeric page ID
629 $page_id = $_POST['selected_id'];
630 if ( ! ctype_digit( $page_id ) ) {
631 die( 'Security check' );
632 }
633
634 if ( 'page' != $_POST['type'] || ! isset( $_POST['selected_id'] ) ) {
635 return;
636 }
637
638 // Publish to Page
639 $options = array(
640 'facebook_page' => $page_id,
641 'facebook_profile' => null
642 );
643
644 $this->set_remote_publicize_options( $_POST['connection'], $options );
645 }
646
647 function options_page_tumblr() {
648 // Nonce check
649 check_admin_referer( 'options_page_tumblr_' . $_REQUEST['connection'] );
650
651 $connected_services = $this->get_all_connections();
652 $connection = $connected_services['tumblr'][ $_POST['connection'] ];
653 $options_to_show = $connection['connection_data']['meta']['options_responses'];
654 $request = $options_to_show[0];
655
656 $blogs = $request['response']['user']['blogs'];
657
658 $blog_selected = false;
659
660 if ( ! empty( $connection['connection_data']['meta']['tumblr_base_hostname'] ) ) {
661 foreach ( $blogs as $blog ) {
662 if ( $connection['connection_data']['meta']['tumblr_base_hostname'] == $this->get_basehostname( $blog['url'] ) ) {
663 $blog_selected = $connection['connection_data']['meta']['tumblr_base_hostname'];
664 break;
665 }
666 }
667
668 }
669
670 // Use their Primary blog if they haven't selected one yet
671 if ( ! $blog_selected ) {
672 foreach ( $blogs as $blog ) {
673 if ( $blog['primary'] ) {
674 $blog_selected = $this->get_basehostname( $blog['url'] );
675 }
676 }
677 } ?>
678
679 <div id="thickbox-content">
680
681 <?php
682 ob_start();
683 Publicize_UI::connected_notice( 'Tumblr' );
684 $update_notice = ob_get_clean();
685
686 if ( ! empty( $update_notice ) ) {
687 echo $update_notice;
688 }
689 ?>
690
691 <p><?php _e( 'Publicize to my <strong>Tumblr blog</strong>:', 'jetpack' ); ?></p>
692
693 <ul id="option-tumblr-blog">
694
695 <?php
696 foreach ( $blogs as $blog ) {
697 $url = $this->get_basehostname( $blog['url'] ); ?>
698 <li>
699 <input type="radio" name="option" data-type="blog" id="<?php echo esc_attr( $url ) ?>"
700 value="<?php echo esc_attr( $url ) ?>" <?php checked( $blog_selected == $url, true ); ?> />
701 <label for="<?php echo esc_attr( $url ) ?>"><span
702 class="name"><?php echo esc_html( $blog['title'] ) ?></span></label>
703 </li>
704 <?php } ?>
705
706 </ul>
707
708 <?php Publicize_UI::global_checkbox( 'tumblr', $_REQUEST['connection'] ); ?>
709
710 <p style="text-align: center;">
711 <input type="submit" value="<?php esc_attr_e( 'OK', 'jetpack' ) ?>"
712 class="button tumblr-options save-options" name="save"
713 data-connection="<?php echo esc_attr( $_REQUEST['connection'] ); ?>"
714 rel="<?php echo wp_create_nonce( 'save_tumblr_blog_' . $_REQUEST['connection'] ) ?>"/>
715 </p> <br/>
716 </div>
717
718 <?php
719 }
720
721 function get_basehostname( $url ) {
722 return parse_url( $url, PHP_URL_HOST );
723 }
724
725 function options_save_tumblr() {
726 // Nonce check
727 check_admin_referer( 'save_tumblr_blog_' . $_REQUEST['connection'] );
728 $options = array( 'tumblr_base_hostname' => $_POST['selected_id'] );
729
730 $this->set_remote_publicize_options( $_POST['connection'], $options );
731
732 }
733
734 function set_remote_publicize_options( $id, $options ) {
735 Jetpack::load_xml_rpc_client();
736 $xml = new Jetpack_IXR_Client();
737 $xml->query( 'jetpack.setPublicizeOptions', $id, $options );
738
739 if ( ! $xml->isError() ) {
740 $response = $xml->getResponse();
741 Jetpack_Options::update_option( 'publicize_connections', $response );
742 $this->globalization();
743 }
744 }
745
746 function options_page_twitter() {
747 Publicize_UI::options_page_other( 'twitter' );
748 }
749
750 function options_page_linkedin() {
751 Publicize_UI::options_page_other( 'linkedin' );
752 }
753
754 function options_page_path() {
755 Publicize_UI::options_page_other( 'path' );
756 }
757
758 function options_page_google_plus() {
759 Publicize_UI::options_page_other( 'google_plus' );
760 }
761
762 function options_save_twitter() {
763 $this->options_save_other( 'twitter' );
764 }
765
766 function options_save_linkedin() {
767 $this->options_save_other( 'linkedin' );
768 }
769
770 function options_save_path() {
771 $this->options_save_other( 'path' );
772 }
773
774 function options_save_google_plus() {
775 $this->options_save_other( 'google_plus' );
776 }
777
778 function options_save_other( $service_name ) {
779 // Nonce check
780 check_admin_referer( 'save_' . $service_name . '_token_' . $_REQUEST['connection'] );
781 $this->globalization();
782 }
783
784 /**
785 * Already-published posts should not be Publicized by default. This filter sets checked to
786 * false if a post has already been published.
787 */
788 function publicize_checkbox_default( $checked, $post_id, $name, $connection ) {
789 if ( 'publish' == get_post_status( $post_id ) ) {
790 return false;
791 }
792
793 return $checked;
794 }
795
796 /**
797 * If there's only one shared connection to Twitter set it as twitter:site tag.
798 */
799 function enhaced_twitter_cards_site_tag( $tag ) {
800 $custom_site_tag = get_option( 'jetpack-twitter-cards-site-tag' );
801 if ( ! empty( $custom_site_tag ) ) {
802 return $tag;
803 }
804 if ( ! $this->is_enabled( 'twitter' ) ) {
805 return $tag;
806 }
807 $connections = $this->get_connections( 'twitter' );
808 foreach ( $connections as $connection ) {
809 $connection_meta = $this->get_connection_meta( $connection );
810 if ( 0 == $connection_meta['connection_data']['user_id'] ) {
811 // If the connection is shared
812 return $this->get_display_name( 'twitter', $connection );
813 }
814 }
815
816 return $tag;
817 }
818
819 function save_publicized_twitter_account( $submit_post, $post_id, $service_name, $connection ) {
820 if ( 'twitter' == $service_name && $submit_post ) {
821 $connection_meta = $this->get_connection_meta( $connection );
822 $publicize_twitter_user = get_post_meta( $post_id, '_publicize_twitter_user' );
823 if ( empty( $publicize_twitter_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
824 update_post_meta( $post_id, '_publicize_twitter_user', $this->get_display_name( 'twitter', $connection ) );
825 }
826 }
827 }
828
829 function get_publicized_twitter_account( $account, $post_id ) {
830 if ( ! empty( $account ) ) {
831 return $account;
832 }
833 $account = get_post_meta( $post_id, '_publicize_twitter_user', true );
834 if ( ! empty( $account ) ) {
835 return $account;
836 }
837
838 return '';
839 }
840
841 /**
842 * Save the Publicized Facebook account when publishing a post
843 * Use only Personal accounts, not Facebook Pages
844 */
845 function save_publicized_facebook_account( $submit_post, $post_id, $service_name, $connection ) {
846 $connection_meta = $this->get_connection_meta( $connection );
847 if ( 'facebook' == $service_name && isset( $connection_meta['connection_data']['meta']['facebook_profile'] ) && $submit_post ) {
848 $publicize_facebook_user = get_post_meta( $post_id, '_publicize_facebook_user' );
849 if ( empty( $publicize_facebook_user ) || 0 != $connection_meta['connection_data']['user_id'] ) {
850 $profile_link = $this->get_profile_link( 'facebook', $connection );
851
852 if ( false !== $profile_link ) {
853 update_post_meta( $post_id, '_publicize_facebook_user', $profile_link );
854 }
855 }
856 }
857 }
858 }
859