PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
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 13.8.3 All 506 releases
← All changes | jetpack_vendor/automattic/jetpack-sync/src/class-settings.php +174 -15 12.2.3 → 16.3-a.7 View file →
@@ -7,8 +7,9 @@
7 7
8 8 namespace Automattic\Jetpack\Sync;
9 9
10 10 use Automattic\Jetpack\Constants;
11 +use Automattic\Jetpack\Sync\Queue\Queue_Storage_Table;
11 12
12 13 /**
13 14 * Class to manage the sync settings.
14 15 */
@@ -58,8 +59,11 @@
58 59 'full_sync_send_duration' => true,
59 60 'full_sync_limits' => true,
60 61 'checksum_disable' => true,
61 62 'dedicated_sync_enabled' => true,
63 + 'custom_queue_table_enabled' => true,
64 + 'wpcom_rest_api_enabled' => true,
65 + 'sync_actions_blacklist' => true,
62 66 );
63 67
64 68 /**
65 69 * Whether WordPress is currently running an import.
@@ -111,9 +115,9 @@
111 115 */
112 116 public static function get_settings() {
113 117 $settings = array();
114 118 foreach ( array_keys( self::$valid_settings ) as $setting ) {
115 - $settings[ $setting ] = self::get_setting( $setting );
119 + $settings[ $setting ] = static::get_setting( $setting );
116 120 }
117 121
118 122 return $settings;
119 123 }
@@ -198,8 +202,90 @@
198 202 public static function update_settings( $new_settings ) {
199 203 $validated_settings = array_intersect_key( $new_settings, self::$valid_settings );
200 204 foreach ( $validated_settings as $setting => $value ) {
201 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;
202 288 if ( self::is_network_setting( $setting ) ) {
203 289 if ( is_multisite() && is_main_site() ) {
204 290 $updated = update_site_option( self::SETTINGS_OPTION_PREFIX . $setting, $value );
205 291 }
@@ -217,8 +303,23 @@
217 303 // Do not enable Dedicated Sync if we cannot spawn a Dedicated Sync request.
218 304 if ( 'dedicated_sync_enabled' === $setting && $updated && (bool) $value ) {
219 305 if ( ! Dedicated_Sender::can_spawn_dedicated_sync_request() ) {
220 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 + }
221 322 }
222 323 }
223 324 }
224 325 }
@@ -232,9 +333,9 @@
232 333 * @param string $setting Setting name.
233 334 * @return boolean Whether the setting is a network setting.
234 335 */
235 336 public static function is_network_setting( $setting ) {
236 - return strpos( $setting, 'network_' ) === 0;
337 + return str_starts_with( $setting, 'network_' );
237 338 }
238 339
239 340 /**
240 341 * Returns escaped SQL for blacklisted post types.
@@ -245,9 +346,9 @@
245 346 *
246 347 * @return string SQL WHERE clause.
247 348 */
248 349 public static function get_blacklisted_post_types_sql() {
249 - return 'post_type NOT IN (\'' . implode( '\', \'', 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' ) ) ) . '\')';
250 351 }
251 352
252 353 /**
253 354 * Returns escaped values for disallowed post types.
@@ -260,9 +361,9 @@
260 361 public static function get_disallowed_post_types_structured() {
261 362 return array(
262 363 'post_type' => array(
263 364 'operator' => 'NOT IN',
264 - 'values' => array_map( 'esc_sql', self::get_setting( 'post_types_blacklist' ) ),
365 + 'values' => array_map( 'esc_sql', static::get_setting( 'post_types_blacklist' ) ),
265 366 ),
266 367 );
267 368 }
268 369
@@ -275,12 +376,30 @@
275 376 *
276 377 * @return string SQL WHERE clause.
277 378 */
278 379 public static function get_blacklisted_taxonomies_sql() {
279 - return "taxonomy NOT IN ('" . implode( "', '", array_map( 'esc_sql', self::get_setting( 'taxonomies_blacklist' ) ) ) . "')";
380 + return "taxonomy NOT IN ('" . implode( "', '", array_map( 'esc_sql', static::get_setting( 'taxonomies_blacklist' ) ) ) . "')";
280 381 }
281 382
282 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 + /**
283 402 * Returns escaped SQL for blacklisted post meta.
284 403 * Can be injected directly into a WHERE clause.
285 404 *
286 405 * @access public
@@ -288,9 +407,9 @@
288 407 *
289 408 * @return string SQL WHERE clause.
290 409 */
291 410 public static function get_whitelisted_post_meta_sql() {
292 - return 'meta_key IN (\'' . implode( '\', \'', 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' ) ) ) . '\')';
293 412 }
294 413
295 414 /**
296 415 * Returns escaped SQL for allowed post meta keys.
@@ -303,9 +422,9 @@
303 422 public static function get_allowed_post_meta_structured() {
304 423 return array(
305 424 'meta_key' => array(
306 425 'operator' => 'IN',
307 - 'values' => array_map( 'esc_sql', self::get_setting( 'post_meta_whitelist' ) ),
426 + 'values' => array_map( 'esc_sql', static::get_setting( 'post_meta_whitelist' ) ),
308 427 ),
309 428 );
310 429 }
311 430
@@ -320,9 +439,9 @@
320 439 public static function get_blacklisted_taxonomies_structured() {
321 440 return array(
322 441 'taxonomy' => array(
323 442 'operator' => 'NOT IN',
324 - 'values' => array_map( 'esc_sql', self::get_setting( 'taxonomies_blacklist' ) ),
443 + 'values' => array_map( 'esc_sql', static::get_setting( 'taxonomies_blacklist' ) ),
325 444 ),
326 445 );
327 446 }
328 447
@@ -337,9 +456,9 @@
337 456 public static function get_allowed_taxonomies_structured() {
338 457 global $wp_taxonomies;
339 458
340 459 $allowed_taxonomies = array_keys( $wp_taxonomies );
341 - $allowed_taxonomies = array_diff( $allowed_taxonomies, self::get_setting( 'taxonomies_blacklist' ) );
460 + $allowed_taxonomies = array_diff( $allowed_taxonomies, static::get_setting( 'taxonomies_blacklist' ) );
342 461 return array(
343 462 'taxonomy' => array(
344 463 'operator' => 'IN',
345 464 'values' => array_map( 'esc_sql', $allowed_taxonomies ),
@@ -356,9 +475,9 @@
356 475 *
357 476 * @return string SQL WHERE clause.
358 477 */
359 478 public static function get_whitelisted_comment_meta_sql() {
360 - return 'meta_key IN (\'' . implode( '\', \'', 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' ) ) ) . '\')';
361 480 }
362 481
363 482 /**
364 483 * Returns SQL-escaped values for allowed post meta keys.
@@ -371,9 +490,9 @@
371 490 public static function get_allowed_comment_meta_structured() {
372 491 return array(
373 492 'meta_key' => array(
374 493 'operator' => 'IN',
375 - 'values' => array_map( 'esc_sql', self::get_setting( 'comment_meta_whitelist' ) ),
494 + 'values' => array_map( 'esc_sql', static::get_setting( 'comment_meta_whitelist' ) ),
376 495 ),
377 496 );
378 497 }
379 498
@@ -401,8 +520,25 @@
401 520 );
402 521 }
403 522
404 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 + /**
405 541 * Returns escaped SQL for comments, excluding any spam comments.
406 542 * Can be injected directly into a WHERE clause.
407 543 *
408 544 * @access public
@@ -468,9 +604,9 @@
468 604 *
469 605 * @return boolean Whether sync is enabled.
470 606 */
471 607 public static function is_sync_enabled() {
472 - return ! ( self::get_setting( 'disable' ) || self::get_setting( 'network_disable' ) );
608 + return ! ( static::get_setting( 'disable' ) || static::get_setting( 'network_disable' ) );
473 609 }
474 610
475 611 /**
476 612 * Set the WP cron state.
@@ -559,9 +695,9 @@
559 695 *
560 696 * @return boolean Whether sync is enabled.
561 697 */
562 698 public static function is_sender_enabled( $queue_id ) {
563 - return (bool) self::get_setting( $queue_id . '_sender_enabled' );
699 + return (bool) static::get_setting( $queue_id . '_sender_enabled' );
564 700 }
565 701
566 702 /**
567 703 * Whether checksums are enabled.
@@ -571,9 +707,9 @@
571 707 *
572 708 * @return boolean Whether sync is enabled.
573 709 */
574 710 public static function is_checksum_enabled() {
575 - return ! (bool) self::get_setting( 'checksum_disable' );
711 + return ! (bool) static::get_setting( 'checksum_disable' );
576 712 }
577 713
578 714 /**
579 715 * Whether dedicated Sync flow is enabled.
@@ -583,8 +719,31 @@
583 719 *
584 720 * @return boolean Whether dedicated Sync flow is enabled.
585 721 */
586 722 public static function is_dedicated_sync_enabled() {
587 - return (bool) self::get_setting( 'dedicated_sync_enabled' );
723 + return (bool) static::get_setting( 'dedicated_sync_enabled' );
588 724 }
589 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 + }
590 749 }