PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
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 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-sync/src/class-settings.php +177 -16 12.0.3 → 16.3-beta View file →
@@ -6,8 +6,11 @@
6 6 */
7 7
8 8 namespace Automattic\Jetpack\Sync;
9 9
10 +use Automattic\Jetpack\Constants;
11 +use Automattic\Jetpack\Sync\Queue\Queue_Storage_Table;
12 +
10 13 /**
11 14 * Class to manage the sync settings.
12 15 */
13 16 class Settings {
@@ -56,8 +59,11 @@
56 59 'full_sync_send_duration' => true,
57 60 'full_sync_limits' => true,
58 61 'checksum_disable' => true,
59 62 'dedicated_sync_enabled' => true,
63 + 'custom_queue_table_enabled' => true,
64 + 'wpcom_rest_api_enabled' => true,
65 + 'sync_actions_blacklist' => true,
60 66 );
61 67
62 68 /**
63 69 * Whether WordPress is currently running an import.
@@ -109,9 +115,9 @@
109 115 */
110 116 public static function get_settings() {
111 117 $settings = array();
112 118 foreach ( array_keys( self::$valid_settings ) as $setting ) {
113 - $settings[ $setting ] = self::get_setting( $setting );
119 + $settings[ $setting ] = static::get_setting( $setting );
114 120 }
115 121
116 122 return $settings;
117 123 }
@@ -196,8 +202,90 @@
196 202 public static function update_settings( $new_settings ) {
197 203 $validated_settings = array_intersect_key( $new_settings, self::$valid_settings );
198 204 foreach ( $validated_settings as $setting => $value ) {
199 205
206 + /**
207 + * Custom table migration logic.
208 + *
209 + * This needs to happen before the option is updated, to avoid race conditions where we update the option,
210 + * but haven't yet created the table or can't create it.
211 + *
212 + * On high-traffic sites this can lead to Sync trying to write in a non-existent table.
213 + *
214 + * So to avoid this, we're going to first try to initialize everything and then update the option.
215 + */
216 + if ( 'custom_queue_table_enabled' === $setting ) {
217 + // Need to check the current value in the database to make sure we're not doing anything weird.
218 + $old_value = get_option( self::SETTINGS_OPTION_PREFIX . $setting, null );
219 +
220 + if ( ! $old_value && $value ) {
221 + /**
222 + * The custom table has been enabled.
223 + *
224 + * - Initialize the custom table
225 + * - Migrate the data
226 + *
227 + * If something fails, migrate back to the options table and clean up everything about the custom table.
228 + */
229 + $init_result = Queue_Storage_Table::initialize_custom_sync_table();
230 +
231 + /**
232 + * Check if there was a problem when initializing the table.
233 + */
234 + if ( is_wp_error( $init_result ) ) {
235 + /**
236 + * Unable to initialize the table properly. Set the value to `false` as we can't enable it.
237 + */
238 + $value = false;
239 +
240 + /**
241 + * Send error to WPCOM, so we can track and take an appropriate action.
242 + */
243 + $data = array(
244 + 'timestamp' => microtime( true ),
245 + 'error_code' => $init_result->get_error_code(),
246 + 'response_body' => $init_result->get_error_message(),
247 + );
248 +
249 + $sender = Sender::get_instance();
250 + $sender->send_action( 'jetpack_sync_storage_error_custom_init', $data );
251 +
252 + } elseif ( ! Queue_Storage_Table::migrate_from_options_table_to_custom_table() ) {
253 + /**
254 + * If the migration fails, do a reverse migration and set the value to `false` as we can't
255 + * safely enable the table.
256 + */
257 + Queue_Storage_Table::migrate_from_custom_table_to_options_table();
258 +
259 + // Set $value to `false` as we couldn't do the migration, and we can't continue enabling the table.
260 + $value = false;
261 +
262 + /**
263 + * Send error to WPCOM, so we can track and take an appropriate action.
264 + */
265 + $data = array(
266 + 'timestamp' => microtime( true ),
267 + // TODO: Maybe add more details here for the migration, i.e. how many items where in the queue?
268 + );
269 +
270 + $sender = Sender::get_instance();
271 + $sender->send_action( 'jetpack_sync_storage_error_custom_migrate', $data );
272 + }
273 + } elseif ( $old_value && ! $value ) {
274 + if ( ! get_transient( Queue_Storage_Table::CUSTOM_QUEUE_TABLE_DISABLE_WPDB_ERROR_NOT_EXIST_FLAG ) ) {
275 + /**
276 + * The custom table has been disabled, migrate what we can from the custom table to the options table unless
277 + * the custom table doesn't exist in the DB.
278 + */
279 + Queue_Storage_Table::migrate_from_custom_table_to_options_table();
280 + }
281 + }
282 + }
283 +
284 + /**
285 + * Regular option update and handling
286 + */
287 + $updated = false;
200 288 if ( self::is_network_setting( $setting ) ) {
201 289 if ( is_multisite() && is_main_site() ) {
202 290 $updated = update_site_option( self::SETTINGS_OPTION_PREFIX . $setting, $value );
203 291 }
@@ -215,8 +303,23 @@
215 303 // Do not enable Dedicated Sync if we cannot spawn a Dedicated Sync request.
216 304 if ( 'dedicated_sync_enabled' === $setting && $updated && (bool) $value ) {
217 305 if ( ! Dedicated_Sender::can_spawn_dedicated_sync_request() ) {
218 306 update_option( self::SETTINGS_OPTION_PREFIX . $setting, 0, true );
307 + $listener = Listener::get_instance();
308 + // Remove the last two actions from the queue since we failed to enable Dedicated Sync.
309 + // Those would be `updated_option` with `jetpack_sync_settings_dedicated_sync_enabled` set to 1 and then 0 again.
310 + $queue = $listener->get_sync_queue();
311 + $items = $queue->peek_newest( 2 );
312 + $key = 'jetpack_sync_settings_dedicated_sync_enabled';
313 +
314 + if (
315 + isset( $items[0][1][0] )
316 + && isset( $items[1][1][0] )
317 + && $items[0][1][0] === $key
318 + && $items[1][1][0] === $key
319 + ) {
320 + $queue->pop_newest( 2 );
321 + }
219 322 }
220 323 }
221 324 }
222 325 }
@@ -230,9 +333,9 @@
230 333 * @param string $setting Setting name.
231 334 * @return boolean Whether the setting is a network setting.
232 335 */
233 336 public static function is_network_setting( $setting ) {
234 - return strpos( $setting, 'network_' ) === 0;
337 + return str_starts_with( $setting, 'network_' );
235 338 }
236 339
237 340 /**
238 341 * Returns escaped SQL for blacklisted post types.
@@ -243,9 +346,9 @@
243 346 *
244 347 * @return string SQL WHERE clause.
245 348 */
246 349 public static function get_blacklisted_post_types_sql() {
247 - return 'post_type NOT IN (\'' . join( '\', \'', array_map( 'esc_sql', self::get_setting( 'post_types_blacklist' ) ) ) . '\')';
350 + return 'post_type NOT IN (\'' . implode( '\', \'', array_map( 'esc_sql', static::get_setting( 'post_types_blacklist' ) ) ) . '\')';
248 351 }
249 352
250 353 /**
251 354 * Returns escaped values for disallowed post types.
@@ -258,9 +361,9 @@
258 361 public static function get_disallowed_post_types_structured() {
259 362 return array(
260 363 'post_type' => array(
261 364 'operator' => 'NOT IN',
262 - 'values' => array_map( 'esc_sql', self::get_setting( 'post_types_blacklist' ) ),
365 + 'values' => array_map( 'esc_sql', static::get_setting( 'post_types_blacklist' ) ),
263 366 ),
264 367 );
265 368 }
266 369
@@ -273,12 +376,30 @@
273 376 *
274 377 * @return string SQL WHERE clause.
275 378 */
276 379 public static function get_blacklisted_taxonomies_sql() {
277 - return "taxonomy NOT IN ('" . join( "', '", array_map( 'esc_sql', self::get_setting( 'taxonomies_blacklist' ) ) ) . "')";
380 + return "taxonomy NOT IN ('" . implode( "', '", array_map( 'esc_sql', static::get_setting( 'taxonomies_blacklist' ) ) ) . "')";
278 381 }
279 382
280 383 /**
384 + * Returns escaped SQL for whitelisted taxonomies.
385 + * Can be injected directly into a WHERE clause.
386 + *
387 + * @access public
388 + * @static
389 + *
390 + * @return string SQL WHERE clause.
391 + */
392 + public static function get_whitelisted_taxonomies_sql() {
393 + global $wp_taxonomies;
394 +
395 + $allowed_taxonomies = array_keys( $wp_taxonomies );
396 + $allowed_taxonomies = array_diff( $allowed_taxonomies, static::get_setting( 'taxonomies_blacklist' ) );
397 +
398 + return "taxonomy IN ('" . implode( "', '", array_map( 'esc_sql', $allowed_taxonomies ) ) . "')";
399 + }
400 +
401 + /**
281 402 * Returns escaped SQL for blacklisted post meta.
282 403 * Can be injected directly into a WHERE clause.
283 404 *
284 405 * @access public
@@ -286,9 +407,9 @@
286 407 *
287 408 * @return string SQL WHERE clause.
288 409 */
289 410 public static function get_whitelisted_post_meta_sql() {
290 - return 'meta_key IN (\'' . join( '\', \'', array_map( 'esc_sql', self::get_setting( 'post_meta_whitelist' ) ) ) . '\')';
411 + return 'meta_key IN (\'' . implode( '\', \'', array_map( 'esc_sql', static::get_setting( 'post_meta_whitelist' ) ) ) . '\')';
291 412 }
292 413
293 414 /**
294 415 * Returns escaped SQL for allowed post meta keys.
@@ -301,9 +422,9 @@
301 422 public static function get_allowed_post_meta_structured() {
302 423 return array(
303 424 'meta_key' => array(
304 425 'operator' => 'IN',
305 - 'values' => array_map( 'esc_sql', self::get_setting( 'post_meta_whitelist' ) ),
426 + 'values' => array_map( 'esc_sql', static::get_setting( 'post_meta_whitelist' ) ),
306 427 ),
307 428 );
308 429 }
309 430
@@ -318,9 +439,9 @@
318 439 public static function get_blacklisted_taxonomies_structured() {
319 440 return array(
320 441 'taxonomy' => array(
321 442 'operator' => 'NOT IN',
322 - 'values' => array_map( 'esc_sql', self::get_setting( 'taxonomies_blacklist' ) ),
443 + 'values' => array_map( 'esc_sql', static::get_setting( 'taxonomies_blacklist' ) ),
323 444 ),
324 445 );
325 446 }
326 447
@@ -335,9 +456,9 @@
335 456 public static function get_allowed_taxonomies_structured() {
336 457 global $wp_taxonomies;
337 458
338 459 $allowed_taxonomies = array_keys( $wp_taxonomies );
339 - $allowed_taxonomies = array_diff( $allowed_taxonomies, self::get_setting( 'taxonomies_blacklist' ) );
460 + $allowed_taxonomies = array_diff( $allowed_taxonomies, static::get_setting( 'taxonomies_blacklist' ) );
340 461 return array(
341 462 'taxonomy' => array(
342 463 'operator' => 'IN',
343 464 'values' => array_map( 'esc_sql', $allowed_taxonomies ),
@@ -354,9 +475,9 @@
354 475 *
355 476 * @return string SQL WHERE clause.
356 477 */
357 478 public static function get_whitelisted_comment_meta_sql() {
358 - return 'meta_key IN (\'' . join( '\', \'', array_map( 'esc_sql', self::get_setting( 'comment_meta_whitelist' ) ) ) . '\')';
479 + return 'meta_key IN (\'' . implode( '\', \'', array_map( 'esc_sql', static::get_setting( 'comment_meta_whitelist' ) ) ) . '\')';
359 480 }
360 481
361 482 /**
362 483 * Returns SQL-escaped values for allowed post meta keys.
@@ -369,9 +490,9 @@
369 490 public static function get_allowed_comment_meta_structured() {
370 491 return array(
371 492 'meta_key' => array(
372 493 'operator' => 'IN',
373 - 'values' => array_map( 'esc_sql', self::get_setting( 'comment_meta_whitelist' ) ),
494 + 'values' => array_map( 'esc_sql', static::get_setting( 'comment_meta_whitelist' ) ),
374 495 ),
375 496 );
376 497 }
377 498
@@ -399,8 +520,25 @@
399 520 );
400 521 }
401 522
402 523 /**
524 + * Returns structured filter values for allowed comment types.
525 + *
526 + * @access public
527 + * @static
528 + *
529 + * @return array Comment type filter values.
530 + */
531 + public static function get_allowed_comment_types_structured() {
532 + return array(
533 + 'comment_type' => array(
534 + 'operator' => 'IN',
535 + 'values' => array_map( 'esc_sql', Defaults::get_comment_types_whitelist() ),
536 + ),
537 + );
538 + }
539 +
540 + /**
403 541 * Returns escaped SQL for comments, excluding any spam comments.
404 542 * Can be injected directly into a WHERE clause.
405 543 *
406 544 * @access public
@@ -466,9 +604,9 @@
466 604 *
467 605 * @return boolean Whether sync is enabled.
468 606 */
469 607 public static function is_sync_enabled() {
470 - return ! ( self::get_setting( 'disable' ) || self::get_setting( 'network_disable' ) );
608 + return ! ( static::get_setting( 'disable' ) || static::get_setting( 'network_disable' ) );
471 609 }
472 610
473 611 /**
474 612 * Set the WP cron state.
@@ -507,9 +645,9 @@
507 645 *
508 646 * @return boolean Whether we are currently syncing.
509 647 */
510 648 public static function is_syncing() {
511 - return (bool) self::$is_syncing || ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST );
649 + return (bool) self::$is_syncing || Constants::is_true( 'REST_API_REQUEST' );
512 650 }
513 651
514 652 /**
515 653 * Set the syncing state.
@@ -557,9 +695,9 @@
557 695 *
558 696 * @return boolean Whether sync is enabled.
559 697 */
560 698 public static function is_sender_enabled( $queue_id ) {
561 - return (bool) self::get_setting( $queue_id . '_sender_enabled' );
699 + return (bool) static::get_setting( $queue_id . '_sender_enabled' );
562 700 }
563 701
564 702 /**
565 703 * Whether checksums are enabled.
@@ -569,9 +707,9 @@
569 707 *
570 708 * @return boolean Whether sync is enabled.
571 709 */
572 710 public static function is_checksum_enabled() {
573 - return ! (bool) self::get_setting( 'checksum_disable' );
711 + return ! (bool) static::get_setting( 'checksum_disable' );
574 712 }
575 713
576 714 /**
577 715 * Whether dedicated Sync flow is enabled.
@@ -581,8 +719,31 @@
581 719 *
582 720 * @return boolean Whether dedicated Sync flow is enabled.
583 721 */
584 722 public static function is_dedicated_sync_enabled() {
585 - return (bool) self::get_setting( 'dedicated_sync_enabled' );
723 + return (bool) static::get_setting( 'dedicated_sync_enabled' );
586 724 }
587 725
726 + /**
727 + * Whether custom queue table is enabled.
728 + *
729 + * @access public
730 + * @static
731 + *
732 + * @return boolean Whether custom queue table is enabled.
733 + */
734 + public static function is_custom_queue_table_enabled() {
735 + return (bool) static::get_setting( 'custom_queue_table_enabled' );
736 + }
737 +
738 + /**
739 + * Whether wpcom rest api is enabled.
740 + *
741 + * @access public
742 + * @static
743 + *
744 + * @return boolean Whether wpcom rest api is enabled.
745 + */
746 + public static function is_wpcom_rest_api_enabled() {
747 + return (bool) static::get_setting( 'wpcom_rest_api_enabled' );
748 + }
588 749 }