PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 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 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-publicize/src/class-publicize.php +109 -187 13.5.2 → 16.3 View file →
@@ -7,9 +7,8 @@
7 7
8 8 namespace Automattic\Jetpack\Publicize;
9 9
10 10 use Automattic\Jetpack\Connection\Client;
11 -use Automattic\Jetpack\Connection\Tokens;
12 11 use Jetpack_IXR_Client;
13 12 use Jetpack_Options;
14 13 use WP_Error;
15 14 use WP_Post;
@@ -28,8 +27,15 @@
28 27 */
29 28 private $test_connection_results = array();
30 29
31 30 /**
31 + * Property to store the results of fetching the connections.
32 + *
33 + * @var null|array
34 + */
35 + private $current_connections = null;
36 +
37 + /**
32 38 * Add hooks.
33 39 */
34 40 public function __construct() {
35 41 parent::__construct();
@@ -35,12 +41,8 @@
35 41 parent::__construct();
36 42
37 43 add_filter( 'jetpack_xmlrpc_unauthenticated_methods', array( $this, 'register_update_publicize_connections_xmlrpc_method' ) );
38 44
39 - add_action( 'load-settings_page_sharing', array( $this, 'admin_page_load' ), 9 );
40 -
41 - add_action( 'load-settings_page_sharing', array( $this, 'force_user_connection' ) );
42 -
43 45 add_filter( 'jetpack_published_post_flags', array( $this, 'set_post_flags' ), 10, 2 );
44 46
45 47 add_action( 'wp_insert_post', array( $this, 'save_publicized' ), 11, 2 );
46 48
@@ -54,83 +56,49 @@
54 56 add_action( 'admin_notices', array( $this, 'display_disconnected' ) );
55 57 }
56 58
57 59 /**
58 - * Whether to use the v1 admin UI.
60 + * Force user connection before showing the Publicize UI.
61 + *
62 + * @deprecated 0.88.0 Settings > Sharing no longer hosts the Publicize UI.
63 + *
64 + * @return void
59 65 */
60 - public function use_admin_ui_v1(): bool {
66 + public function force_user_connection() {
67 + _deprecated_function( __METHOD__, 'publicize-0.88.0' );
68 + }
61 69
62 - // If the option is set, use it.
63 - if ( get_option( 'jetpack_social_use_admin_ui_v1', false ) ) {
64 - return true;
65 - }
66 -
67 - // Otherwise, check the constant and the plan feature.
68 - return ( defined( 'JETPACK_SOCIAL_USE_ADMIN_UI_V1' ) && JETPACK_SOCIAL_USE_ADMIN_UI_V1 )
69 - || $this->has_connections_management_feature();
70 + /**
71 + * Show a warning when Publicize does not have a connection.
72 + *
73 + * @deprecated 0.88.0 Settings > Sharing no longer hosts the Publicize UI.
74 + *
75 + * @return void
76 + */
77 + public function admin_page_warning() {
78 + _deprecated_function( __METHOD__, 'publicize-0.88.0' );
70 79 }
71 80
72 81 /**
73 - * Force user connection before showing the Publicize UI.
82 + * Show error on settings page if applicable.
83 + *
84 + * @deprecated 0.88.0 Settings > Sharing no longer hosts connection errors.
85 + *
86 + * @return void
74 87 */
75 - public function force_user_connection() {
76 - global $current_user;
77 -
78 - $user_token = ( new Tokens() )->get_access_token( $current_user->ID );
79 - $is_user_connected = $user_token && ! is_wp_error( $user_token );
80 -
81 - // If the user is already connected via Jetpack, then we're good.
82 - if ( $is_user_connected ) {
83 - return;
84 - }
85 -
86 - // If they're not connected, then remove the Publicize UI and tell them they need to connect first.
87 - global $publicize_ui;
88 - remove_action( 'pre_admin_screen_sharing', array( $publicize_ui, 'admin_page' ) );
89 -
90 - // Do we really need `admin_styles`? With the new admin UI, it's breaking some bits.
91 - // Jetpack::init()->admin_styles();.
92 - add_action( 'pre_admin_screen_sharing', array( $this, 'admin_page_warning' ), 1 );
88 + public function admin_page_load() {
89 + _deprecated_function( __METHOD__, 'publicize-0.88.0' );
93 90 }
94 91
95 92 /**
96 - * Show a warning when Publicize does not have a connection.
93 + * Display an error message.
94 + *
95 + * @deprecated 0.88.0 Settings > Sharing no longer hosts connection errors.
96 + *
97 + * @return void
97 98 */
98 - public function admin_page_warning() {
99 - $jetpack = \Jetpack::init();
100 - $blog_name = get_bloginfo( 'blogname' );
101 - if ( empty( $blog_name ) ) {
102 - $blog_name = home_url( '/' );
103 - }
104 -
105 - ?>
106 - <div id="message" class="updated jetpack-message jp-connect">
107 - <div class="jetpack-wrap-container">
108 - <div class="jetpack-text-container">
109 - <p>
110 - <?php
111 - printf(
112 - /* translators: %s is the name of the blog */
113 - esc_html( wptexturize( __( "To use Jetpack Social, you'll need to link your %s account to your WordPress.com account using the link below.", 'jetpack-publicize-pkg' ) ) ),
114 - '<strong>' . esc_html( $blog_name ) . '</strong>'
115 - );
116 - ?>
117 - </p>
118 - <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-publicize-pkg' ) ) ); ?></p>
119 - </div>
120 - <div class="jetpack-install-container">
121 - <p class="submit"><a
122 - href="<?php echo esc_url( $jetpack->build_connect_url( false, menu_page_url( 'sharing', false ) ) ); ?>"
123 - class="button-connector"
124 - id="wpcom-connect"><?php esc_html_e( 'Link account with WordPress.com', 'jetpack-publicize-pkg' ); ?></a>
125 - </p>
126 - <p class="jetpack-install-blurb">
127 - <?php jetpack_render_tos_blurb(); ?>
128 - </p>
129 - </div>
130 - </div>
131 - </div>
132 - <?php
99 + public function display_connection_error() {
100 + _deprecated_function( __METHOD__, 'publicize-0.88.0' );
133 101 }
134 102
135 103 /**
136 104 * Remove a Publicize Connection.
@@ -152,15 +120,66 @@
152 120 * @param mixed $publicize_connections Updated connections.
153 121 * @return true
154 122 */
155 123 public function receive_updated_publicize_connections( $publicize_connections ) {
156 - set_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT, $publicize_connections, 3600 * 4 );
124 +
125 + $publicize_connections = self::filter_usable_connections( $publicize_connections );
126 +
127 + // Populate the cache with the new data.
128 + Connections::get_all( array( 'ignore_cache' => true ) );
129 +
130 + $expiry = 3600 * 4;
131 + if ( ! set_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT, $publicize_connections, $expiry ) ) {
132 + // If the transient has beeen set in another request, the call to set_transient can fail. If so,
133 + // we can delete the transient and try again.
134 + $this->clear_connections_transient();
135 + set_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT, $publicize_connections, $expiry );
136 + }
137 + // Regardless of whether the transient is set ok, let's set and use the local property for this request.
138 + $this->current_connections = $publicize_connections;
157 139 return true;
158 140 }
159 141
160 142 /**
143 + * Drop connections we cannot attribute to a user.
144 + *
145 + * A missing user ID reads as "shared with everyone" in is_global_connection(), so such a
146 + * connection would be exposed to every user on the site. User ID 0 is a genuine shared
147 + * connection and is kept; unknown fields pass through, as WPCOM adds to this payload.
148 + *
149 + * @param mixed $publicize_connections Connections, keyed by service name.
150 + * @return array
151 + */
152 + private static function filter_usable_connections( $publicize_connections ) {
153 + // An empty payload is valid - it means the site has no connections left.
154 + if ( ! is_array( $publicize_connections ) ) {
155 + return array();
156 + }
157 +
158 + $usable_connections = array();
159 +
160 + foreach ( $publicize_connections as $service_name => $connections_for_service ) {
161 + if ( ! is_array( $connections_for_service ) ) {
162 + continue;
163 + }
164 +
165 + foreach ( $connections_for_service as $id => $connection ) {
166 + if ( ! isset( $connection['connection_data']['user_id'] ) || ! is_numeric( $connection['connection_data']['user_id'] ) ) {
167 + continue;
168 + }
169 +
170 + $usable_connections[ $service_name ][ $id ] = $connection;
171 + }
172 + }
173 +
174 + return $usable_connections;
175 + }
176 +
177 + /**
161 178 * Add method to update Publicize connections.
162 179 *
180 + * @todo Kept as a fallback for the jetpack/v4/publicize/connections/sync REST endpoint that replaced it; remove after a few releases (CONNECT-446).
181 + *
163 182 * @param array $methods Array of registered methods.
164 183 * @return array
165 184 */
166 185 public function register_update_publicize_connections_xmlrpc_method( $methods ) {
@@ -181,11 +200,11 @@
181 200 */
182 201 public function get_all_connections() {
183 202 $this->refresh_connections();
184 203
185 - $connections = get_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT );
204 + $connections = $this->current_connections;
186 205
187 - if ( $connections === false ) {
206 + if ( empty( $connections ) ) {
188 207 $connections = array();
189 208 }
190 209
191 210 if ( isset( $connections['google_plus'] ) ) {
@@ -228,9 +247,8 @@
228 247 /**
229 248 * Get all connections for a specific user.
230 249 *
231 250 * @param array $args Arguments to run operations such as force refresh and connection test results.
232 -
233 251 * @return array
234 252 */
235 253 public function get_all_connections_for_user( $args = array() ) {
236 254 if ( ( isset( $args['clear_cache'] ) && $args['clear_cache'] )
@@ -243,34 +261,15 @@
243 261 if ( ! empty( $connections ) ) {
244 262 foreach ( (array) $connections as $service_name => $connections_for_service ) {
245 263 foreach ( $connections_for_service as $id => $connection ) {
246 264 $user_id = (int) $connection['connection_data']['user_id'];
247 - // phpcs:ignore WordPress.PHP.YodaConditions.NotYoda
248 265 if ( $user_id === 0 || $this->user_id() === $user_id ) {
249 - if ( $this->use_admin_ui_v1() ) {
250 - $connections_to_return[] = array_merge(
251 - $connection,
252 - array(
253 - 'service_name' => $service_name,
254 - 'connection_id' => $connection['connection_data']['id'],
255 - 'can_disconnect' => self::can_manage_connection( $connection['connection_data'] ),
256 - 'profile_link' => $this->get_profile_link( $service_name, $connection ),
257 - 'shared' => $connection['connection_data']['user_id'] === '0',
258 - 'status' => 'ok',
259 - )
260 - );
261 - } else {
262 - $connections_to_return[ $service_name ][ $id ] = $connection;
263 - }
266 + $connections_to_return[ $service_name ][ $id ] = $connection;
264 267 }
265 268 }
266 269 }
267 270 }
268 271
269 - if ( self::use_admin_ui_v1() && isset( $args['test_connections'] ) && $args['test_connections'] && count( $connections_to_return ) > 0 ) {
270 - $connections_to_return = $this->add_connection_test_results( $connections_to_return );
271 - }
272 -
273 272 return $connections_to_return;
274 273 }
275 274
276 275 /**
@@ -345,91 +344,8 @@
345 344 return $connection;
346 345 }
347 346
348 347 /**
349 - * Show error on settings page if applicable.
350 - */
351 - public function admin_page_load() {
352 - $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
353 -
354 - if ( 'error' === $action ) {
355 - add_action( 'pre_admin_screen_sharing', array( $this, 'display_connection_error' ), 9 );
356 - }
357 - }
358 -
359 - /**
360 - * Display an error message.
361 - */
362 - public function display_connection_error() {
363 - $code = false;
364 - // phpcs:disable WordPress.Security.NonceVerification.Recommended
365 - $service = isset( $_GET['service'] ) ? sanitize_text_field( wp_unslash( $_GET['service'] ) ) : null;
366 - $publicize_error = isset( $_GET['publicize_error'] ) ? sanitize_text_field( wp_unslash( $_GET['publicize_error'] ) ) : null;
367 - // phpcs:enable WordPress.Security.NonceVerification.Recommended
368 -
369 - if ( $service ) {
370 - /* translators: %s is the name of the Jetpack Social service (e.g. Facebook, Twitter) */
371 - $error = sprintf( __( 'There was a problem connecting to %s to create an authorized connection. Please try again in a moment.', 'jetpack-publicize-pkg' ), self::get_service_label( $service ) );
372 - } elseif ( $publicize_error ) {
373 - $code = strtolower( $publicize_error );
374 - switch ( $code ) {
375 - case '400':
376 - $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-publicize-pkg' );
377 - break;
378 - case 'secret_mismatch':
379 - $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-publicize-pkg' );
380 - break;
381 - case 'empty_blog_id':
382 - $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 Jetpack Social again.', 'jetpack-publicize-pkg' );
383 - break;
384 - case 'empty_state':
385 - /* translators: %s is the URL of the Jetpack admin page */
386 - $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-publicize-pkg' ), \Jetpack::admin_url() );
387 - break;
388 - default:
389 - $error = __( 'Something which should never happen, happened. Sorry about that. If you try again, maybe it will work.', 'jetpack-publicize-pkg' );
390 - break;
391 - }
392 - } else {
393 - $error = __( 'There was a problem connecting with Jetpack Social. Please try again in a moment.', 'jetpack-publicize-pkg' );
394 - }
395 - // Using the same formatting/style as Jetpack::admin_notices() error.
396 - ?>
397 - <div id="message" class="jetpack-message jetpack-err">
398 - <div class="squeezer">
399 - <h2>
400 - <?php
401 - echo wp_kses(
402 - $error,
403 - array(
404 - 'a' => array(
405 - 'href' => true,
406 - ),
407 - 'code' => true,
408 - 'strong' => true,
409 - 'br' => true,
410 - 'b' => true,
411 - )
412 - );
413 - ?>
414 - </h2>
415 - <?php if ( $code ) : ?>
416 - <p>
417 - <?php
418 - printf(
419 - /* translators: %s is the name of the error */
420 - esc_html__( 'Error code: %s', 'jetpack-publicize-pkg' ),
421 - esc_html( stripslashes( $code ) )
422 - );
423 - ?>
424 - </p>
425 - <?php endif; ?>
426 - </div>
427 - </div>
428 - <?php
429 - }
430 -
431 - /**
432 348 * Show a message that the connection has been removed.
433 349 */
434 350 public function display_disconnected() {
435 351 echo "<div class='updated'>\n";
@@ -485,19 +401,23 @@
485 401 /**
486 402 * Grabs a fresh copy of the publicize connections data, if the cache is busted.
487 403 */
488 404 public function refresh_connections() {
405 + if ( null !== $this->current_connections ) {
406 + return;
407 + }
408 +
489 409 $connections = get_transient( self::JETPACK_SOCIAL_CONNECTIONS_TRANSIENT );
490 - if ( $connections === false ) {
410 + if ( false === $connections ) {
491 411 $xml = new Jetpack_IXR_Client();
492 412 $xml->query( 'jetpack.fetchPublicizeConnections' );
493 413 if ( ! $xml->isError() ) {
494 414 $response = $xml->getResponse();
495 415 $this->receive_updated_publicize_connections( $response );
496 - } else {
497 - $this->clear_connections_transient();
498 416 }
417 + return;
499 418 }
419 + $this->current_connections = $connections;
500 420 }
501 421
502 422 /**
503 423 * Delete the transient.
@@ -560,8 +480,10 @@
560 480 'tumblr' => array(),
561 481 'mastodon' => array(),
562 482 'instagram-business' => array(),
563 483 'nextdoor' => array(),
484 + 'threads' => array(),
485 + 'bluesky' => array(),
564 486 );
565 487
566 488 if ( 'all' === $filter ) {
567 489 return $services;
@@ -597,9 +519,9 @@
597 519 * @param string $old_status Old status of the post.
598 520 * @param WP_Post $post Post object.
599 521 */
600 522 public function flag_post_for_publicize( $new_status, $old_status, $post ) {
601 - if ( ! $this->post_type_is_publicizeable( $post->post_type ) ) {
523 + if ( ! $post instanceof \WP_Post || ! $this->post_type_is_publicizeable( $post->post_type ) ) {
602 524 return;
603 525 }
604 526
605 527 $should_publicize = $this->should_submit_post_pre_checks( $post );
@@ -661,10 +583,10 @@
661 583 }
662 584
663 585 $error_data = array(
664 586 'user_can_refresh' => $user_can_refresh,
665 - 'refresh_text' => $refresh_text,
666 - 'refresh_url' => $refresh_url,
587 + 'refresh_text' => $refresh_text ?? null,
588 + 'refresh_url' => $refresh_url ?? null,
667 589 );
668 590
669 591 $this->test_connection_results[ $id ] = new WP_Error( $connection_error_code, $connection_test_message, $error_data );
670 592
@@ -687,9 +609,9 @@
687 609 */
688 610 public function post_is_done_sharing( $post_id = null ) {
689 611 // Defaults to current post if $post_id is null.
690 612 $post = get_post( $post_id );
691 - if ( $post === null ) {
613 + if ( null === $post ) {
692 614 return false;
693 615 }
694 616
695 617 return 'publish' === $post->post_status || get_post_meta( $post->ID, $this->POST_DONE . 'all', true ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
@@ -702,14 +624,14 @@
702 624 * @param int $post_ID Post ID.
703 625 * @param WP_Post $post Post object.
704 626 */
705 627 public function save_publicized( $post_ID, $post = null ) {
706 - if ( $post === null ) {
628 + if ( null === $post ) {
707 629 return;
708 630 }
709 631 // Only do this when a post transitions to being published.
710 632 // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
711 - if ( get_post_meta( $post->ID, $this->PENDING ) && $this->post_type_is_publicizeable( $post->post_type ) ) {
633 + if ( get_post_meta( $post->ID, $this->PENDING, false ) && $this->post_type_is_publicizeable( $post->post_type ) ) {
712 634 delete_post_meta( $post->ID, $this->PENDING );
713 635 update_post_meta( $post->ID, $this->POST_DONE . 'all', true );
714 636 }
715 637 // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
@@ -744,5 +666,5 @@
744 666 $flags['publicize_post'] = true;
745 667
746 668 return $flags;
747 669 }
748 -}
670 +}