summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYury German <blueknight@gentoo.org>2022-06-15 12:08:35 -0400
committerYury German <blueknight@gentoo.org>2022-06-15 12:08:35 -0400
commit36d7691c33cb64ece817246e47a779ec648d10b0 (patch)
tree08f2fb95303a1d8eeba2c8629a24b35a91fb1cac /plugins/jetpack/jetpack_vendor/automattic/jetpack-sync
parenttwentyfourteen upg 2.7 to 3.2 and twentysixteen from 2.0 to 2.5 (diff)
downloadblogs-gentoo-36d7691c33cb64ece817246e47a779ec648d10b0.tar.gz
blogs-gentoo-36d7691c33cb64ece817246e47a779ec648d10b0.tar.bz2
blogs-gentoo-36d7691c33cb64ece817246e47a779ec648d10b0.zip
Openid-3.6.1 and jetpack-11.0 upgrade
Signed-off-by: Yury German <blueknight@gentoo.org>
Diffstat (limited to 'plugins/jetpack/jetpack_vendor/automattic/jetpack-sync')
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/CHANGELOG.md130
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-actions.php101
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-data-settings.php355
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-dedicated-sender.php204
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-default-filter-settings.php80
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-defaults.php13
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-functions.php50
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-listener.php9
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-main.php11
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-package-version.php2
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-queue.php15
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php2
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-rest-endpoints.php43
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-sender.php54
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-settings.php28
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-users.php6
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-callables.php7
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-constants.php2
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync-immediately.php5
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync.php4
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php6
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php4
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-search.php1846
23 files changed, 2937 insertions, 40 deletions
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/CHANGELOG.md b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/CHANGELOG.md
index aca0a702..531c86f0 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/CHANGELOG.md
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/CHANGELOG.md
@@ -5,6 +5,115 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.35.0] - 2022-05-30
+### Changed
+- Sync: Add '_jetpack_blogging_prompt_key' to default post meta whitelist
+
+## [1.34.0] - 2022-05-24
+### Changed
+- Dedicated Sync - Introduce custom endpoint for spawning Sync requests [#24468]
+- Sync: Add 'active_modules' to default whitelisted callables. [#24453]
+
+## [1.33.1] - 2022-05-19
+### Removed
+- Removed dedicated sync custom endpoints pending error investigation [#24419]
+
+## [1.33.0] - 2022-05-18
+### Changed
+- Dedicated Sync: Introduce custom endpoint for spawning Sync requests [#24344]
+
+## [1.32.0] - 2022-05-10
+### Added
+- Search: add search options to option whitelist [#24167]
+
+## [1.31.1] - 2022-05-04
+### Changed
+- Updated package dependencies. [#24095]
+- WordPress 6.1 Compatibilty [#24083]
+
+### Deprecated
+- Moved the options class into Connection. [#24095]
+
+## [1.31.0] - 2022-04-26
+### Added
+- Adds filter to get_themes callable
+
+### Deprecated
+- Removed Heartbeat by hoisting it into Connection.
+
+## [1.30.8] - 2022-04-19
+### Added
+- Added get_themes Callable to sync the list of installed themes on a site
+- Added get_themes to Sync defaults
+
+### Changed
+- PHPCS: Fix `WordPress.Security.ValidatedSanitizedInput`
+- Updated package dependencies.
+
+## [1.30.7] - 2022-04-12
+### Added
+- Adding new site option to be synced.
+
+## [1.30.6] - 2022-04-06
+### Changed
+- Updated package dependencies.
+
+### Fixed
+- Dedicated Sync: Only try to run the sender once if Dedicated Sync is enabled as it has its own requeueing mechanism.
+
+## [1.30.5] - 2022-03-29
+### Changed
+- Microperformance: Use === null instead of is_null
+
+## [1.30.4] - 2022-03-23
+### Changed
+- Enable syncing of dedicated_sync_enabled Sync setting
+
+### Fixed
+- Dedicated Sync: Allow spawning request with expired Retry-After
+
+## [1.30.3] - 2022-03-15
+### Changed
+- Search Sync Settings :: Add ETB taxonomy to allow list.
+
+## [1.30.2] - 2022-03-08
+### Changed
+- Disallow syncing of _term_meta post_type
+
+## [1.30.1] - 2022-03-02
+### Added
+- Dedicated Sync flow: Allow enabling or disabling via WPCOM response header
+
+## [1.30.0] - 2022-02-22
+### Added
+- Add Sync dedicated request flow.
+
+### Changed
+- Updated package dependencies.
+
+## [1.29.2] - 2022-02-09
+### Added
+- Allow sync package consumers to provide custom data settings.
+
+### Fixed
+- Fixed some new PHPCS warnings.
+
+## [1.29.1] - 2022-02-02
+### Changed
+- Updated package dependencies.
+
+## [1.29.0] - 2022-01-25
+### Added
+- Jetpack Search: update the allowed post meta when search is active to include all indexable meta.
+
+## [1.28.2] - 2022-01-18
+### Changed
+- Updated package dependencies.
+
+## [1.28.1] - 2022-01-13
+### Changed
+- Updated package dependencies.
+
## [1.28.0] - 2022-01-04
### Changed
- Listener: Do not enqueue actions when the site is disconnected
@@ -550,6 +659,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Packages: Move sync to a classmapped package
+[1.35.0]: https://github.com/Automattic/jetpack-sync/compare/v1.34.0...v1.35.0
+[1.34.0]: https://github.com/Automattic/jetpack-sync/compare/v1.33.1...v1.34.0
+[1.33.1]: https://github.com/Automattic/jetpack-sync/compare/v1.33.0...v1.33.1
+[1.33.0]: https://github.com/Automattic/jetpack-sync/compare/v1.32.0...v1.33.0
+[1.32.0]: https://github.com/Automattic/jetpack-sync/compare/v1.31.1...v1.32.0
+[1.31.1]: https://github.com/Automattic/jetpack-sync/compare/v1.31.0...v1.31.1
+[1.31.0]: https://github.com/Automattic/jetpack-sync/compare/v1.30.8...v1.31.0
+[1.30.8]: https://github.com/Automattic/jetpack-sync/compare/v1.30.7...v1.30.8
+[1.30.7]: https://github.com/Automattic/jetpack-sync/compare/v1.30.6...v1.30.7
+[1.30.6]: https://github.com/Automattic/jetpack-sync/compare/v1.30.5...v1.30.6
+[1.30.5]: https://github.com/Automattic/jetpack-sync/compare/v1.30.4...v1.30.5
+[1.30.4]: https://github.com/Automattic/jetpack-sync/compare/v1.30.3...v1.30.4
+[1.30.3]: https://github.com/Automattic/jetpack-sync/compare/v1.30.2...v1.30.3
+[1.30.2]: https://github.com/Automattic/jetpack-sync/compare/v1.30.1...v1.30.2
+[1.30.1]: https://github.com/Automattic/jetpack-sync/compare/v1.30.0...v1.30.1
+[1.30.0]: https://github.com/Automattic/jetpack-sync/compare/v1.29.2...v1.30.0
+[1.29.2]: https://github.com/Automattic/jetpack-sync/compare/v1.29.1...v1.29.2
+[1.29.1]: https://github.com/Automattic/jetpack-sync/compare/v1.29.0...v1.29.1
+[1.29.0]: https://github.com/Automattic/jetpack-sync/compare/v1.28.2...v1.29.0
+[1.28.2]: https://github.com/Automattic/jetpack-sync/compare/v1.28.1...v1.28.2
+[1.28.1]: https://github.com/Automattic/jetpack-sync/compare/v1.28.0...v1.28.1
[1.28.0]: https://github.com/Automattic/jetpack-sync/compare/v1.27.6...v1.28.0
[1.27.6]: https://github.com/Automattic/jetpack-sync/compare/v1.27.5...v1.27.6
[1.27.5]: https://github.com/Automattic/jetpack-sync/compare/v1.27.4...v1.27.5
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-actions.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-actions.php
index e2f05c98..768ade58 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-actions.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-actions.php
@@ -89,6 +89,8 @@ class Actions {
/**
* Initialize Sync for cron jobs, set up listeners for WordPress Actions,
* and set up a shut-down action for sending actions to WordPress.com
+ * If dedicated Sync is enabled and this is a dedicated Sync request
+ * up an init action for sending actions to WordPress.com instead.
*
* @access public
* @static
@@ -99,6 +101,15 @@ class Actions {
return;
}
+ // If dedicated Sync is enabled and this is a dedicated Sync request, no need to
+ // initialize Sync for cron jobs, set up listeners or set up a shut-down action
+ // for sending actions to WordPress.com.
+ // We only need to set up an init action for sending actions to WordPress.com and exit early.
+ if ( Settings::is_dedicated_sync_enabled() && Dedicated_Sender::is_dedicated_sync_request() ) {
+ add_action( 'init', array( __CLASS__, 'add_dedicated_sync_sender_init' ), 90 );
+ return;
+ }
+
if ( self::sync_via_cron_allowed() ) {
self::init_sync_cron_jobs();
} elseif ( wp_next_scheduled( 'jetpack_sync_cron' ) ) {
@@ -164,6 +175,22 @@ class Actions {
}
/**
+ * Immediately sends actions on init for the current dedicated Sync request.
+ *
+ * @access public
+ * @static
+ */
+ public static function add_dedicated_sync_sender_init() {
+ if ( apply_filters(
+ 'jetpack_sync_sender_should_load',
+ true
+ ) ) {
+ self::initialize_sender();
+ self::$sender->do_dedicated_sync_and_exit();
+ }
+ }
+
+ /**
* Define JETPACK_SYNC_READ_ONLY constant if not defined.
* This notifies sync to not run in shutdown if it was initialized during init.
*
@@ -194,6 +221,13 @@ class Actions {
return self::sync_via_cron_allowed();
}
+ /**
+ * For now, if dedicated Sync is enabled we will always initialize send, even for GET and unauthenticated requests.
+ */
+ if ( Settings::is_dedicated_sync_enabled() ) {
+ return true;
+ }
+
if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) {
return true;
}
@@ -379,14 +413,16 @@ class Actions {
public static function send_data( $data, $codec_name, $sent_timestamp, $queue_id, $checkout_duration, $preprocess_duration, $queue_size = null, $buffer_id = null ) {
$query_args = array(
- 'sync' => '1', // Add an extra parameter to the URL so we can tell it's a sync action.
- 'codec' => $codec_name,
- 'timestamp' => $sent_timestamp,
- 'queue' => $queue_id,
- 'cd' => sprintf( '%.4f', $checkout_duration ),
- 'pd' => sprintf( '%.4f', $preprocess_duration ),
- 'queue_size' => $queue_size,
- 'buffer_id' => $buffer_id,
+ 'sync' => '1', // Add an extra parameter to the URL so we can tell it's a sync action.
+ 'codec' => $codec_name,
+ 'timestamp' => $sent_timestamp,
+ 'queue' => $queue_id,
+ 'cd' => sprintf( '%.4f', $checkout_duration ),
+ 'pd' => sprintf( '%.4f', $preprocess_duration ),
+ 'queue_size' => $queue_size,
+ 'buffer_id' => $buffer_id,
+ // TODO this will be extended in the future. Might be good to extract in a separate method to support future entries too.
+ 'sync_flow_type' => Settings::is_dedicated_sync_enabled() ? 'dedicated' : 'default',
);
$query_args['timeout'] = Settings::is_doing_cron() ? 30 : 20;
@@ -437,6 +473,17 @@ class Actions {
}
}
+ // Enable/Disable Dedicated Sync flow via response headers.
+ $dedicated_sync_header = $rpc->get_response_header( 'Jetpack-Dedicated-Sync' );
+ if ( false !== $dedicated_sync_header ) {
+ $dedicated_sync_enabled = 'on' === $dedicated_sync_header ? 1 : 0;
+ Settings::update_settings(
+ array(
+ 'dedicated_sync_enabled' => $dedicated_sync_enabled,
+ )
+ );
+ }
+
if ( ! $result ) {
if ( false === $retry_after ) {
// We received a non standard response from WP.com, lets backoff from sending requests for 1 minute.
@@ -631,6 +678,14 @@ class Actions {
break;
}
+ /**
+ * Only try to sync once if Dedicated Sync is enabled. Dedicated Sync has its own requeueing mechanism
+ * that will re-run it if there are items in the queue at the end.
+ */
+ if ( 'sync' === $type && $executions >= 1 && Settings::is_dedicated_sync_enabled() ) {
+ break;
+ }
+
$result = 'full_sync' === $type ? self::$sender->do_full_sync() : self::$sender->do_sync();
// # of send actions performed.
@@ -676,6 +731,36 @@ class Actions {
}
/**
+ * Initializes sync for Instant Search.
+ *
+ * @access public
+ * @static
+ */
+ public static function initialize_search() {
+ if ( false === class_exists( 'Automattic\\Jetpack\\Search\\Module_Control' ) ) {
+ return;
+ }
+ $search_module = new \Automattic\Jetpack\Search\Module_Control();
+ if ( $search_module->is_instant_search_enabled() ) {
+ add_filter( 'jetpack_sync_modules', array( __CLASS__, 'add_search_sync_module' ) );
+ }
+ }
+
+ /**
+ * Add Search updates to Sync Filters.
+ *
+ * @access public
+ * @static
+ *
+ * @param array $sync_modules The list of sync modules declared prior to this filter.
+ * @return array A list of sync modules that now includes Search's modules.
+ */
+ public static function add_search_sync_module( $sync_modules ) {
+ $sync_modules[] = 'Automattic\\Jetpack\\Sync\\Modules\\Search';
+ return $sync_modules;
+ }
+
+ /**
* Adds Woo's sync modules to existing modules for sending.
*
* @access public
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-data-settings.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-data-settings.php
new file mode 100644
index 00000000..fa2adae4
--- /dev/null
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-data-settings.php
@@ -0,0 +1,355 @@
+<?php
+/**
+ * The Data Settings class.
+ *
+ * @package automattic/jetpack-sync
+ */
+
+namespace Automattic\Jetpack\Sync;
+
+/**
+ * The Data_Settings class
+ */
+class Data_Settings {
+
+ /**
+ * The data that must be synced for every synced site.
+ */
+ const MUST_SYNC_DATA_SETTINGS = array(
+ 'jetpack_sync_modules' => array(
+ 'Automattic\\Jetpack\\Sync\\Modules\\Callables',
+ 'Automattic\\Jetpack\\Sync\\Modules\\Full_Sync_Immediately', // enable Initial Sync on Site Connection.
+ ),
+ 'jetpack_sync_callable_whitelist' => array(
+ 'site_url' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'site_url' ),
+ 'home_url' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'home_url' ),
+ 'paused_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_plugins' ),
+ 'paused_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_themes' ),
+ ),
+ );
+
+ const MODULE_FILTER_MAPPING = array(
+ 'Automattic\\Jetpack\\Sync\\Modules\\Options' => array(
+ 'jetpack_sync_options_whitelist',
+ 'jetpack_sync_options_contentless',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Constants' => array(
+ 'jetpack_sync_constants_whitelist',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Callables' => array(
+ 'jetpack_sync_callable_whitelist',
+ 'jetpack_sync_multisite_callable_whitelist',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Posts' => array(
+ 'jetpack_sync_post_meta_whitelist',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Comments' => array(
+ 'jetpack_sync_comment_meta_whitelist',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Users' => array(
+ 'jetpack_sync_capabilities_whitelist',
+ ),
+ 'Automattic\\Jetpack\\Sync\\Modules\\Import' => array(
+ 'jetpack_sync_known_importers',
+ ),
+ );
+
+ const MODULES_FILTER_NAME = 'jetpack_sync_modules';
+
+ /**
+ * The static data settings array which contains the aggregated data settings for
+ * each sync filter.
+ *
+ * @var array
+ */
+ private static $data_settings = array();
+
+ /**
+ * The static array which contains the list of filter hooks that have already been set up.
+ *
+ * @var array
+ */
+ private static $set_filter_hooks = array();
+
+ /**
+ * Adds the data settings provided by a plugin to the Sync data settings.
+ *
+ * @param array $plugin_settings The array provided by the plugin. The array must use filters
+ * from the DATA_FILTER_DEFAULTS list as keys.
+ */
+ public function add_settings_list( $plugin_settings = array() ) {
+ if ( empty( $plugin_settings[ self::MODULES_FILTER_NAME ] )
+ || ! is_array( $plugin_settings[ self::MODULES_FILTER_NAME ] ) ) {
+ /*
+ * No modules have been set, so use defaults for everything and bail early.
+ */
+ $this->set_all_defaults();
+ return;
+ }
+
+ $this->add_filters_custom_settings_and_hooks( $plugin_settings );
+
+ if ( ! did_action( 'jetpack_sync_add_required_data_settings' ) ) {
+ $this->add_required_settings();
+ /**
+ * Fires when the required settings have been adding to the static
+ * data_settings array.
+ *
+ * @since 1.29.2
+ *
+ * @module sync
+ */
+ do_action( 'jetpack_sync_add_required_data_settings' );
+ }
+ }
+
+ /**
+ * Sets the default values for sync modules and all sync data filters.
+ */
+ private function set_all_defaults() {
+ $this->add_sync_filter_setting( self::MODULES_FILTER_NAME, Modules::DEFAULT_SYNC_MODULES );
+
+ foreach ( array_keys( Default_Filter_Settings::DATA_FILTER_DEFAULTS ) as $filter ) {
+ $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
+ }
+ }
+
+ /**
+ * Returns the default settings for the given filter.
+ *
+ * @param string $filter The filter name.
+ *
+ * @return array The filter's default settings array.
+ */
+ private function get_default_setting_for_filter( $filter ) {
+ if ( self::MODULES_FILTER_NAME === $filter ) {
+ return Modules::DEFAULT_SYNC_MODULES;
+ }
+
+ return ( new Default_Filter_Settings() )->get_default_settings( $filter );
+ }
+
+ /**
+ * Adds the custom settings and sets up the necessary filter hooks.
+ *
+ * @param array $filters_settings The custom settings.
+ */
+ private function add_filters_custom_settings_and_hooks( $filters_settings ) {
+ if ( ! isset( $filters_settings[ self::MODULES_FILTER_NAME ] ) ) {
+ // This shouldn't happen.
+ return;
+ }
+
+ $this->add_custom_filter_setting( self::MODULES_FILTER_NAME, $filters_settings[ self::MODULES_FILTER_NAME ] );
+
+ $enabled_modules = $filters_settings[ self::MODULES_FILTER_NAME ];
+ $all_modules = Modules::DEFAULT_SYNC_MODULES;
+
+ foreach ( $all_modules as $module ) {
+ if ( in_array( $module, $enabled_modules, true ) ) {
+ $this->add_filters_for_enabled_module( $module, $filters_settings );
+ } else {
+ $this->add_filters_for_disabled_module( $module );
+ }
+ }
+ }
+
+ /**
+ * Adds the filters for the provided enabled module. If the settings provided custom filter settings
+ * for the module's filters, those are used. Otherwise, the filter's default settings are used.
+ *
+ * @param string $module The module name.
+ * @param array $filters_settings The settings for the filters.
+ */
+ private function add_filters_for_enabled_module( $module, $filters_settings ) {
+ $module_mapping = self::MODULE_FILTER_MAPPING;
+ $filters_for_module = isset( $module_mapping[ $module ] ) ? $module_mapping[ $module ] : array();
+
+ foreach ( $filters_for_module as $filter ) {
+ if ( isset( $filters_settings[ $filter ] ) ) {
+ $this->add_custom_filter_setting( $filter, $filters_settings[ $filter ] );
+ } else {
+ $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
+ }
+ }
+ }
+
+ /**
+ * Adds the filters for the provided disabled module. The disabled module's associated filter settings are
+ * set to an empty array.
+ *
+ * @param string $module The module name.
+ */
+ private function add_filters_for_disabled_module( $module ) {
+ $module_mapping = self::MODULE_FILTER_MAPPING;
+ $filters_for_module = isset( $module_mapping[ $module ] ) ? $module_mapping[ $module ] : array();
+
+ foreach ( $filters_for_module as $filter ) {
+ $this->add_custom_filter_setting( $filter, array() );
+ }
+ }
+
+ /**
+ * Adds the provided custom setting for a filter. If the filter setting isn't valid, the default
+ * value is used.
+ *
+ * If the filter's hook hasn't already been set up, it gets set up.
+ *
+ * @param string $filter The filter.
+ * @param array $setting The filter setting.
+ */
+ private function add_custom_filter_setting( $filter, $setting ) {
+ if ( ! $this->is_valid_filter_setting( $filter, $setting ) ) {
+ /*
+ * The provided setting isn't valid, so use the default for this filter.
+ * We're using the default values so there's no need to set the filter hook.
+ */
+ $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
+ return;
+ }
+
+ if ( ! isset( static::$set_filter_hooks[ $filter ] ) ) {
+ // First time a custom modules setting is provided, so set the filter hook.
+ add_filter( $filter, array( $this, 'sync_data_filter_hook' ) );
+ static::$set_filter_hooks[ $filter ] = 1;
+ }
+
+ $this->add_sync_filter_setting( $filter, $setting );
+ }
+
+ /**
+ * Determines whether the filter setting is valid. The setting array is in the correct format (associative or indexed).
+ *
+ * @param string $filter The filter to check.
+ * @param array $filter_settings The filter settings.
+ *
+ * @return bool Whether the filter settings can be used.
+ */
+ private function is_valid_filter_setting( $filter, $filter_settings ) {
+ if ( ! is_array( $filter_settings ) ) {
+ // The settings for each filter must be an array.
+ return false;
+ }
+
+ if ( empty( $filter_settings ) ) {
+ // Empty settings are allowed.
+ return true;
+ }
+
+ $indexed_array = isset( $filter_settings[0] );
+ if ( in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) && ! $indexed_array ) {
+ return true;
+ } elseif ( ! in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) && $indexed_array ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds the data settings that are always required for every plugin that uses Sync.
+ */
+ private function add_required_settings() {
+ foreach ( self::MUST_SYNC_DATA_SETTINGS as $filter => $setting ) {
+ $this->add_custom_filter_setting( $filter, $setting );
+ }
+ }
+
+ /**
+ * Adds the provided data setting for the provided filter.
+ *
+ * @param string $filter The filter name.
+ * @param array $value The data setting.
+ */
+ private function add_sync_filter_setting( $filter, $value ) {
+ if ( ! isset( static::$data_settings[ $filter ] ) ) {
+ static::$data_settings[ $filter ] = $value;
+ return;
+ }
+
+ if ( in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) ) {
+ $this->add_associative_filter_setting( $filter, $value );
+ } else {
+ $this->add_indexed_filter_setting( $filter, $value );
+ }
+ }
+
+ /**
+ * Adds the provided data setting for the provided filter. This method handles
+ * adding settings to data that is stored as an associative array.
+ *
+ * @param string $filter The filter name.
+ * @param array $settings The data settings.
+ */
+ private function add_associative_filter_setting( $filter, $settings ) {
+ foreach ( $settings as $key => $item ) {
+ if ( ! array_key_exists( $key, static::$data_settings[ $filter ] ) ) {
+ static::$data_settings[ $filter ][ $key ] = $item;
+ }
+ }
+ }
+
+ /**
+ * Adds the provided data setting for the provided filter. This method handles
+ * adding settings to data that is stored as an indexed array.
+ *
+ * @param string $filter The filter name.
+ * @param array $settings The data settings.
+ */
+ private function add_indexed_filter_setting( $filter, $settings ) {
+ static::$data_settings[ $filter ] = array_unique(
+ array_merge(
+ static::$data_settings[ $filter ],
+ $settings
+ )
+ );
+ }
+
+ /**
+ * The callback function added to the sync data filters. Combines the list in the $data_settings property
+ * with any non-default values from the received array.
+ *
+ * @param array $filtered_values The data revieved from the filter.
+ *
+ * @return array The data settings for the filter.
+ */
+ public function sync_data_filter_hook( $filtered_values ) {
+ if ( ! is_array( $filtered_values ) ) {
+ // Something is wrong with the input, so set it to an empty array.
+ $filtered_values = array();
+ }
+
+ $current_filter = current_filter();
+
+ if ( ! isset( static::$data_settings[ $current_filter ] ) ) {
+ return $filtered_values;
+ }
+
+ if ( in_array( $current_filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) ) {
+ $extra_filters = array_diff_key( $filtered_values, $this->get_default_setting_for_filter( $current_filter ) );
+ $this->add_associative_filter_setting( $current_filter, $extra_filters );
+ return static::$data_settings[ $current_filter ];
+ }
+
+ $extra_filters = array_diff( $filtered_values, $this->get_default_setting_for_filter( $current_filter ) );
+ $this->add_indexed_filter_setting( $current_filter, $extra_filters );
+ return static::$data_settings[ $current_filter ];
+ }
+
+ /**
+ * Sets the $data_settings property to an empty array. This is useful for testing.
+ */
+ public function empty_data_settings_and_hooks() {
+ static::$data_settings = array();
+ static::$set_filter_hooks = array();
+ }
+
+ /**
+ * Returns the $data_settings property.
+ *
+ * @return array The data_settings property.
+ */
+ public function get_data_settings() {
+ return static::$data_settings;
+ }
+}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-dedicated-sender.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-dedicated-sender.php
new file mode 100644
index 00000000..0d068766
--- /dev/null
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-dedicated-sender.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Dedicated Sender.
+ *
+ * The class is responsible for spawning dedicated Sync requests.
+ *
+ * @package automattic/jetpack-sync
+ */
+
+namespace Automattic\Jetpack\Sync;
+
+use WP_Error;
+/**
+ * Class to manage Sync spawning.
+ * The purpose of this class is to provide the means to unblock Sync
+ * from running in the shutdown hook of regular requests by spawning a
+ * dedicated Sync request instead which will trigger Sync to run.
+ */
+class Dedicated_Sender {
+
+ /**
+ * The transient name for storing the response code
+ * after spawning a dedicated sync test request.
+ */
+ const DEDICATED_SYNC_CHECK_TRANSIENT = 'jetpack_sync_dedicated_sync_spawn_check';
+
+ /**
+ * Validation string to check if the endpoint is working correctly.
+ *
+ * This is extracted and not hardcoded, as we might want to change it in the future.
+ */
+ const DEDICATED_SYNC_VALIDATION_STRING = 'DEDICATED SYNC OK';
+
+ /**
+ * Filter a URL to check if Dedicated Sync is enabled.
+ * We need to remove slashes and then run it through `urldecode` as sometimes the
+ * URL is in an encoded form, depending on server configuration.
+ *
+ * @param string $url The URL to filter.
+ *
+ * @return string
+ */
+ public static function prepare_url_for_dedicated_request_check( $url ) {
+ return urldecode( $url );
+ }
+ /**
+ * Check if this request should trigger Sync to run.
+ *
+ * @access public
+ *
+ * @return boolean True if this is a 'jetpack/v4/sync/spawn-sync', false otherwise.
+ */
+ public static function is_dedicated_sync_request() {
+ /**
+ * Check $_SERVER['REQUEST_URI'] first, to see if we're in the right context.
+ * This is done to make sure we can hook in very early in the initialization of WordPress to
+ * be able to send sync requests to the backend as fast as possible, without needing to continue
+ * loading things for the request.
+ */
+ if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
+ return false;
+ }
+
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
+ $check_url = self::prepare_url_for_dedicated_request_check( wp_unslash( $_SERVER['REQUEST_URI'] ) );
+ if ( strpos( $check_url, 'jetpack/v4/sync/spawn-sync' ) !== false ) {
+ return true;
+ }
+
+ /**
+ * If the above check failed, we might have an issue with detecting calls to the REST endpoint early on.
+ * Sometimes, like when permalinks are disabled, the REST path is sent via the `rest_route` GET parameter.
+ * We want to check it too, to make sure we managed to cover more cases and be more certain we actually
+ * catch calls to the endpoint.
+ */
+ if ( ! isset( $_GET['rest_route'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ return false;
+ }
+
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
+ $check_url = self::prepare_url_for_dedicated_request_check( wp_unslash( $_GET['rest_route'] ) );
+ if ( strpos( $check_url, 'jetpack/v4/sync/spawn-sync' ) !== false ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Send a request to run Sync for a certain sync queue
+ * through HTTP request that doesn't halt page loading.
+ *
+ * @access public
+ *
+ * @param Automattic\Jetpack\Sync\Queue $queue Queue object.
+ *
+ * @return boolean|WP_Error True if spawned, WP_Error otherwise.
+ */
+ public static function spawn_sync( $queue ) {
+ if ( ! Settings::is_dedicated_sync_enabled() ) {
+ return new WP_Error( 'dedicated_sync_disabled', 'Dedicated Sync flow is disabled.' );
+ }
+
+ if ( $queue->is_locked() ) {
+ return new WP_Error( 'locked_queue_' . $queue->id );
+ }
+
+ if ( $queue->size() === 0 ) {
+ return new WP_Error( 'empty_queue_' . $queue->id );
+ }
+
+ // Return early if we've gotten a retry-after header response that is not expired.
+ $retry_time = get_option( Actions::RETRY_AFTER_PREFIX . $queue->id );
+ if ( $retry_time && $retry_time >= microtime( true ) ) {
+ return new WP_Error( 'retry_after_' . $queue->id );
+ }
+
+ // Don't sync if we are throttled.
+ $sync_next_time = Sender::get_instance()->get_next_sync_time( $queue->id );
+ if ( $sync_next_time > microtime( true ) ) {
+ return new WP_Error( 'sync_throttled_' . $queue->id );
+ }
+
+ $url = rest_url( 'jetpack/v4/sync/spawn-sync' );
+ $url = add_query_arg( 'time', time(), $url ); // Enforce Cache busting.
+ $args = array(
+ 'cookies' => $_COOKIE,
+ 'blocking' => false,
+ 'timeout' => 0.01,
+ /** This filter is documented in wp-includes/class-wp-http-streams.php */
+ 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
+ );
+
+ $result = wp_remote_get( $url, $args );
+ if ( is_wp_error( $result ) ) {
+ return $result;
+ }
+
+ return true;
+ }
+
+ /**
+ * Test Sync spawning functionality by making a request to the
+ * Sync spawning endpoint and storing the result (status code) in a transient.
+ *
+ * @since $$next_version$$
+ *
+ * @return bool True if we got a successful response, false otherwise.
+ */
+ public static function can_spawn_dedicated_sync_request() {
+ $dedicated_sync_check_transient = self::DEDICATED_SYNC_CHECK_TRANSIENT;
+
+ $dedicated_sync_response_body = get_transient( $dedicated_sync_check_transient );
+
+ if ( false === $dedicated_sync_response_body ) {
+ $url = rest_url( 'jetpack/v4/sync/spawn-sync' );
+ $url = add_query_arg( 'time', time(), $url ); // Enforce Cache busting.
+ $args = array(
+ 'cookies' => $_COOKIE,
+ 'timeout' => 30,
+ /** This filter is documented in wp-includes/class-wp-http-streams.php */
+ 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
+ );
+
+ $response = wp_remote_get( $url, $args );
+ $dedicated_sync_response_code = wp_remote_retrieve_response_code( $response );
+ $dedicated_sync_response_body = trim( wp_remote_retrieve_body( $response ) );
+
+ /**
+ * Limit the size of the body that we save in the transient to avoid cases where an error
+ * occurs and a whole generated HTML page is returned. We don't need to store the whole thing.
+ *
+ * The regexp check is done to make sure we can detect the string even if the body returns some additional
+ * output, like some caching plugins do when they try to pad the request.
+ */
+ $regexp = '!' . preg_quote( self::DEDICATED_SYNC_VALIDATION_STRING, '!' ) . '!uis';
+ if ( preg_match( $regexp, $dedicated_sync_response_body ) ) {
+ $saved_response_body = self::DEDICATED_SYNC_VALIDATION_STRING;
+ } else {
+ $saved_response_body = time();
+ }
+
+ set_transient( $dedicated_sync_check_transient, $saved_response_body, HOUR_IN_SECONDS );
+
+ // Send a bit more information to WordPress.com to help debugging issues.
+ if ( $saved_response_body !== self::DEDICATED_SYNC_VALIDATION_STRING ) {
+ $data = array(
+ 'timestamp' => microtime( true ),
+ 'response_code' => $dedicated_sync_response_code,
+ 'response_body' => $dedicated_sync_response_body,
+
+ // Send the flow type that was attempted.
+ 'sync_flow_type' => 'dedicated',
+ );
+
+ $sender = Sender::get_instance();
+
+ $sender->send_action( 'jetpack_sync_flow_error_enable', $data );
+ }
+ }
+
+ return self::DEDICATED_SYNC_VALIDATION_STRING === $dedicated_sync_response_body;
+ }
+}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-default-filter-settings.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-default-filter-settings.php
new file mode 100644
index 00000000..81946fe8
--- /dev/null
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-default-filter-settings.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * The Default Filter Settings class.
+ *
+ * This class provides the default whitelist values for the Sync data filters.
+ * See the DATA_FILTER_DEFAULTS constant for the list of filters.
+ *
+ * @package automattic/jetpack-sync
+ */
+
+namespace Automattic\Jetpack\Sync;
+
+/**
+ * The Default_Filter_Settings class
+ */
+class Default_Filter_Settings {
+
+ /**
+ * The class that contains the default values of the filters.
+ */
+ const DEFAULT_FILTER_CLASS = 'Automattic\Jetpack\Sync\Defaults';
+
+ /**
+ * A map of each Sync filter name to the associated property name in the Defaults class.
+ */
+ const DATA_FILTER_DEFAULTS = array(
+ 'jetpack_sync_options_whitelist' => 'default_options_whitelist',
+ 'jetpack_sync_options_contentless' => 'default_options_contentless',
+ 'jetpack_sync_constants_whitelist' => 'default_constants_whitelist',
+ 'jetpack_sync_callable_whitelist' => 'default_callable_whitelist',
+ 'jetpack_sync_multisite_callable_whitelist' => 'default_multisite_callable_whitelist',
+ 'jetpack_sync_post_meta_whitelist' => 'post_meta_whitelist',
+ 'jetpack_sync_comment_meta_whitelist' => 'comment_meta_whitelist',
+ 'jetpack_sync_capabilities_whitelist' => 'default_capabilities_whitelist',
+ 'jetpack_sync_known_importers' => 'default_known_importers',
+ );
+
+ /**
+ * The data associated with these filters are stored as associative arrays.
+ * (All other filters store data as indexed arrays.)
+ */
+ const ASSOCIATIVE_FILTERS = array(
+ 'jetpack_sync_callable_whitelist',
+ 'jetpack_sync_multisite_callable_whitelist',
+ 'jetpack_sync_known_importers',
+ );
+
+ /**
+ * Returns the default data settings list for the provided filter.
+ *
+ * @param string $filter The filter name.
+ *
+ * @return array|false The default list of data settings. Returns false if the provided
+ * filter doesn't not have an array of default settings.
+ */
+ public function get_default_settings( $filter ) {
+ if ( ! is_string( $filter ) || ! array_key_exists( $filter, self::DATA_FILTER_DEFAULTS ) ) {
+ return false;
+ }
+
+ $property = self::DATA_FILTER_DEFAULTS[ $filter ];
+ $class = self::DEFAULT_FILTER_CLASS;
+ return $class::$$property;
+ }
+
+ /**
+ * Returns an array containing the default values for all of the filters shown
+ * in DATA_FILTER_DEFAULTS.
+ *
+ * @return array The array containing all sync data filters and their default values.
+ */
+ public function get_all_filters_default_settings() {
+ $defaults = array();
+
+ foreach ( self::DATA_FILTER_DEFAULTS as $filter => $default_location ) {
+ $defaults[ $filter ] = $this->get_default_settings( $filter );
+ }
+ return $defaults;
+ }
+}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-defaults.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-defaults.php
index c8c43501..4386c88f 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-defaults.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-defaults.php
@@ -95,6 +95,7 @@ class Defaults {
'jetpack_sync_settings_post_meta_whitelist',
'jetpack_sync_settings_post_types_blacklist',
'jetpack_sync_settings_taxonomies_blacklist',
+ 'jetpack_sync_settings_dedicated_sync_enabled', // is Dedicated Sync flow enabled.
'jetpack_testimonial',
'jetpack_testimonial_posts_per_page',
'jetpack_wga',
@@ -171,6 +172,7 @@ class Defaults {
'wpcom_is_fse_activated',
'wpcom_publish_comments_with_markdown',
'wpcom_publish_posts_with_markdown',
+ 'videopress_private_enabled_for_site',
);
/**
@@ -282,6 +284,7 @@ class Defaults {
*/
public static $default_callable_whitelist = array(
'get_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins' ),
+ 'get_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_themes' ),
'get_plugins_action_links' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins_action_links' ),
'has_file_system_write_access' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'file_system_write_access' ),
'home_url' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'home_url' ),
@@ -309,6 +312,7 @@ class Defaults {
'wp_get_environment_type' => 'wp_get_environment_type',
'wp_max_upload_size' => 'wp_max_upload_size',
'wp_version' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'wp_version' ),
+ 'active_modules' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_active_modules' ),
);
/**
@@ -375,6 +379,7 @@ class Defaults {
* @var array Blacklisted post types.
*/
public static $blacklisted_post_types = array(
+ '_term_meta',
'ai1ec_event',
'ai_log', // Logger - https://github.com/alleyinteractive/logger.
'amp_validated_url', // AMP Validation Errors.
@@ -728,6 +733,7 @@ class Defaults {
'switch_like_status',
'videopress_guid',
'vimeo_poster_image',
+ '_jetpack_blogging_prompt_key',
);
/**
@@ -1269,4 +1275,11 @@ class Defaults {
),
);
+ /**
+ * Default for enabling dedicated Sync flow.
+ *
+ * @var int Bool-ish. Default 0.
+ */
+ public static $default_dedicated_sync_enabled = 0;
+
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-functions.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-functions.php
index 02de16cd..b007c695 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-functions.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-functions.php
@@ -9,6 +9,7 @@ namespace Automattic\Jetpack\Sync;
use Automattic\Jetpack\Connection\Urls;
use Automattic\Jetpack\Constants;
+use Automattic\Jetpack\Modules as Jetpack_Modules;
/**
* Utility functions to generate data synced to wpcom
@@ -72,7 +73,7 @@ class Functions {
$cloned_taxonomy = json_decode( wp_json_encode( $taxonomy ) );
// recursive taxonomies are no fun.
- if ( is_null( $cloned_taxonomy ) ) {
+ if ( $cloned_taxonomy === null ) {
return null;
}
// Remove any meta_box_cb if they are not the default wp ones.
@@ -82,7 +83,7 @@ class Functions {
}
// Remove update call back.
if ( isset( $cloned_taxonomy->update_count_callback ) &&
- ! is_null( $cloned_taxonomy->update_count_callback ) ) {
+ $cloned_taxonomy->update_count_callback !== null ) {
$cloned_taxonomy->update_count_callback = null;
}
// Remove rest_controller_class if it something other then the default.
@@ -466,7 +467,7 @@ class Functions {
}
$plugins_action_links = get_option( 'jetpack_plugin_api_action_links', array() );
if ( ! empty( $plugins_action_links ) ) {
- if ( is_null( $plugin_file_singular ) ) {
+ if ( $plugin_file_singular === null ) {
return $plugins_action_links;
}
return ( isset( $plugins_action_links[ $plugin_file_singular ] ) ? $plugins_action_links[ $plugin_file_singular ] : null );
@@ -628,4 +629,47 @@ class Functions {
return $any;
}
+
+ /**
+ * Return the list of installed themes
+ *
+ * @since 1.31.0
+ *
+ * @return array
+ */
+ public static function get_themes() {
+ $current_stylesheet = get_stylesheet();
+ $installed_themes = wp_get_themes();
+ $synced_headers = array( 'Name', 'ThemeURI', 'Author', 'Version', 'Template', 'Status', 'TextDomain', 'RequiresWP', 'RequiresPHP' );
+ $themes = array();
+ foreach ( $installed_themes as $stylesheet => $theme ) {
+ $themes[ $stylesheet ] = array();
+ foreach ( $synced_headers as $header ) {
+ $themes[ $stylesheet ][ $header ] = $theme->get( $header );
+ }
+ $themes[ $stylesheet ]['active'] = $stylesheet === $current_stylesheet;
+ if ( method_exists( $theme, 'is_block_theme' ) ) {
+ $themes[ $stylesheet ]['is_block_theme'] = $theme->is_block_theme();
+ }
+ }
+ /**
+ * Filters the output of Sync's get_theme callable
+ *
+ * @since 1.31.0
+ *
+ * @param array $themes The list of installed themes formatted in an array with a collection of information extracted from the Theme's headers
+ */
+ return apply_filters( 'jetpack_sync_get_themes_callable', $themes );
+ }
+
+ /**
+ * Return the list of active Jetpack modules.
+ *
+ * @since $$next_version$$
+ *
+ * @return array
+ */
+ public static function get_active_modules() {
+ return ( new Jetpack_Modules() )->get_active();
+ }
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-listener.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-listener.php
index ce2862a4..37040d00 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-listener.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-listener.php
@@ -240,7 +240,7 @@ class Listener {
*/
$args = apply_filters( "jetpack_sync_before_enqueue_$action_name", $args );
$action_data = array( $args );
- if ( ! is_null( $previous_end ) ) {
+ if ( $previous_end !== null ) {
$action_data[] = $previous_end;
}
// allow listeners to abort.
@@ -426,7 +426,7 @@ class Listener {
);
if ( $this->should_send_user_data_with_actor( $current_filter ) ) {
- $ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '';
+ $ip = isset( $_SERVER['REMOTE_ADDR'] ) ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
if ( defined( 'JETPACK__PLUGIN_DIR' ) ) {
if ( ! function_exists( 'jetpack_protect_get_ip' ) ) {
require_once JETPACK__PLUGIN_DIR . 'modules/protect/shared-functions.php';
@@ -435,7 +435,7 @@ class Listener {
}
$actor['ip'] = $ip;
- $actor['user_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'unknown';
+ $actor['user_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? filter_var( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : 'unknown';
}
return $actor;
@@ -480,7 +480,8 @@ class Listener {
*/
public function get_request_url() {
if ( isset( $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'] ) ) {
- return 'http' . ( isset( $_SERVER['HTTPS'] ) ? 's' : '' ) . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- False positive, sniff misses the call to esc_url_raw.
+ return esc_url_raw( 'http' . ( isset( $_SERVER['HTTPS'] ) ? 's' : '' ) . '://' . wp_unslash( "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" ) );
}
return is_admin() ? get_admin_url( get_current_blog_id() ) : home_url();
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-main.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-main.php
index b7e590a9..b3998c90 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-main.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-main.php
@@ -46,6 +46,16 @@ class Main {
}
/**
+ * Sets the Sync data settings.
+ *
+ * @param array $data_settings An array containing the Sync data options. An empty array indicates that the default
+ * values will be used for all Sync data.
+ */
+ public static function set_sync_data_options( $data_settings = array() ) {
+ ( new Data_Settings() )->add_settings_list( $data_settings );
+ }
+
+ /**
* Initialize the main sync actions.
*
* @action plugins_loaded
@@ -58,6 +68,7 @@ class Main {
* For now additional modules are enabled based on whether the third party plugin
* class exists or not.
*/
+ Sync_Actions::initialize_search();
Sync_Actions::initialize_woocommerce();
Sync_Actions::initialize_wp_super_cache();
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-package-version.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-package-version.php
index 69a9faf3..55383a00 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-package-version.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-package-version.php
@@ -12,7 +12,7 @@ namespace Automattic\Jetpack\Sync;
*/
class Package_Version {
- const PACKAGE_VERSION = '1.28.0';
+ const PACKAGE_VERSION = '1.35.0';
const PACKAGE_SLUG = 'sync';
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-queue.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-queue.php
index fe80cf90..bf8cf812 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-queue.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-queue.php
@@ -411,7 +411,7 @@ class Queue {
if ( is_wp_error( $is_valid ) ) {
// Always delete ids_to_remove even when buffer is no longer checked-out.
// They were processed by WP.com so safe to remove from queue.
- if ( ! is_null( $ids_to_remove ) ) {
+ if ( $ids_to_remove !== null ) {
$this->delete( $ids_to_remove );
}
return $is_valid;
@@ -420,7 +420,7 @@ class Queue {
$this->delete_checkout_id();
// By default clear all items in the buffer.
- if ( is_null( $ids_to_remove ) ) {
+ if ( $ids_to_remove === null ) {
$ids_to_remove = $buffer->get_item_ids();
}
@@ -478,6 +478,15 @@ class Queue {
}
/**
+ * Checks if the queue is locked.
+ *
+ * @return bool
+ */
+ public function is_locked() {
+ return (bool) $this->get_checkout_id();
+ }
+
+ /**
* Locks checkouts from the queue
* tries to wait up to $timeout seconds for the queue to be empty.
*
@@ -735,7 +744,7 @@ class Queue {
}
// TODO: change to strict comparison.
- if ( $checkout_id != $buffer->id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
+ if ( $checkout_id != $buffer->id ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual
return new WP_Error( 'buffer_mismatch', 'The buffer you checked in was not checked out' );
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php
index 6687fec5..ae947009 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-replicastore.php
@@ -1319,7 +1319,7 @@ class Replicastore implements Replicastore_Interface {
}
// Validate / Determine Buckets.
- if ( is_null( $buckets ) || $buckets < 1 ) {
+ if ( $buckets === null || $buckets < 1 ) {
$buckets = $this->calculate_buckets( $table, $start_id, $end_id );
}
if ( is_wp_error( $buckets ) ) {
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-rest-endpoints.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-rest-endpoints.php
index ae12ff32..6e4cb8c9 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-rest-endpoints.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-rest-endpoints.php
@@ -306,6 +306,17 @@ class REST_Endpoints {
)
);
+ // Trigger Dedicated Sync request.
+ register_rest_route(
+ 'jetpack/v4',
+ '/sync/spawn-sync',
+ array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => __CLASS__ . '::spawn_sync',
+ 'permission_callback' => '__return_true',
+ )
+ );
+
}
/**
@@ -726,6 +737,38 @@ class REST_Endpoints {
}
/**
+ * This endpoint is used by Sync to spawn a
+ * dedicated Sync request which will trigger Sync to run.
+ *
+ * If Dedicated Sync is enabled, this callback should never run as
+ * processing of Sync actions will occur earlier and exit.
+ *
+ * @see Actions::init
+ * @see Sender::do_dedicated_sync_and_exit
+ *
+ * @since $$next_version$$
+ *
+ * @return \WP_REST_Response
+ */
+ public static function spawn_sync() {
+ nocache_headers();
+
+ if ( ! Settings::is_dedicated_sync_enabled() ) {
+ return new WP_Error(
+ 'dedicated_sync_disabled',
+ 'Dedicated Sync flow is disabled.',
+ array( 'status' => 422 )
+ );
+ }
+
+ return new WP_Error(
+ 'dedicated_sync_failed',
+ 'Failed to process Dedicated Sync request',
+ array( 'status' => 500 )
+ );
+ }
+
+ /**
* Verify that request has default permissions to perform sync actions.
*
* @since 1.23.1
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-sender.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-sender.php
index 6699dd61..757ce490 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-sender.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-sender.php
@@ -321,7 +321,59 @@ class Sender {
* @return boolean|WP_Error True if this sync sending was successful, error object otherwise.
*/
public function do_sync() {
- return $this->do_sync_and_set_delays( $this->sync_queue );
+ if ( ! Settings::is_dedicated_sync_enabled() ) {
+ $result = $this->do_sync_and_set_delays( $this->sync_queue );
+ } else {
+ $result = Dedicated_Sender::spawn_sync( $this->sync_queue );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Trigger incremental sync and early exit on Dedicated Sync request.
+ *
+ * @access public
+ *
+ * @param bool $do_real_exit If we should exit at the end of the request. We should by default.
+ * In the context of running this in the REST API, we actually want to return an error.
+ *
+ * @return void|WP_Error
+ */
+ public function do_dedicated_sync_and_exit( $do_real_exit = true ) {
+ nocache_headers();
+
+ if ( ! Settings::is_dedicated_sync_enabled() ) {
+ return new WP_Error( 'dedicated_sync_disabled', 'Dedicated Sync flow is disabled.' );
+ }
+
+ if ( ! Dedicated_Sender::is_dedicated_sync_request() ) {
+ return new WP_Error( 'non_dedicated_sync_request', 'Not a Dedicated Sync request.' );
+ }
+
+ /**
+ * Output an `OK` to show that Dedicated Sync is enabled and we can process events.
+ * This is used to test the feature is working.
+ *
+ * @see \Automattic\Jetpack\Sync\Dedicated_Sender::can_spawn_dedicated_sync_request
+ */
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo Dedicated_Sender::DEDICATED_SYNC_VALIDATION_STRING;
+
+ // Try to disconnect the request as quickly as possible and process things in the background.
+ $this->fastcgi_finish_request();
+
+ // Actually try to send Sync events.
+ $result = $this->do_sync_and_set_delays( $this->sync_queue );
+
+ // If no errors occurred, re-spawn a dedicated Sync request.
+ if ( true === $result ) {
+ Dedicated_Sender::spawn_sync( $this->sync_queue );
+ }
+
+ if ( $do_real_exit ) {
+ exit;
+ }
}
/**
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-settings.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-settings.php
index a923fbf3..31cee3b2 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-settings.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-settings.php
@@ -56,6 +56,7 @@ class Settings {
'full_sync_send_duration' => true,
'full_sync_limits' => true,
'checksum_disable' => true,
+ 'dedicated_sync_enabled' => true,
);
/**
@@ -198,10 +199,10 @@ class Settings {
if ( self::is_network_setting( $setting ) ) {
if ( is_multisite() && is_main_site() ) {
- update_site_option( self::SETTINGS_OPTION_PREFIX . $setting, $value );
+ $updated = update_site_option( self::SETTINGS_OPTION_PREFIX . $setting, $value );
}
} else {
- update_option( self::SETTINGS_OPTION_PREFIX . $setting, $value, true );
+ $updated = update_option( self::SETTINGS_OPTION_PREFIX . $setting, $value, true );
}
// If we set the disabled option to true, clear the queues.
@@ -210,6 +211,13 @@ class Settings {
$listener->get_sync_queue()->reset();
$listener->get_full_sync_queue()->reset();
}
+
+ // Do not enable Dedicated Sync if we cannot spawn a Dedicated Sync request.
+ if ( 'dedicated_sync_enabled' === $setting && $updated && (bool) $value ) {
+ if ( ! Dedicated_Sender::can_spawn_dedicated_sync_request() ) {
+ update_option( self::SETTINGS_OPTION_PREFIX . $setting, 0, true );
+ }
+ }
}
}
@@ -443,7 +451,7 @@ class Settings {
* @return boolean Whether WordPress is currently importing.
*/
public static function is_importing() {
- if ( ! is_null( self::$is_importing ) ) {
+ if ( self::$is_importing !== null ) {
return self::$is_importing;
}
@@ -484,7 +492,7 @@ class Settings {
* @return boolean Whether WordPress is currently doing WP cron.
*/
public static function is_doing_cron() {
- if ( ! is_null( self::$is_doing_cron ) ) {
+ if ( self::$is_doing_cron !== null ) {
return self::$is_doing_cron;
}
@@ -565,4 +573,16 @@ class Settings {
return ! (bool) self::get_setting( 'checksum_disable' );
}
+ /**
+ * Whether dedicated Sync flow is enabled.
+ *
+ * @access public
+ * @static
+ *
+ * @return boolean Whether dedicated Sync flow is enabled.
+ */
+ public static function is_dedicated_sync_enabled() {
+ return (bool) self::get_setting( 'dedicated_sync_enabled' );
+ }
+
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-users.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-users.php
index 8a8c83f8..316df9ce 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-users.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/class-users.php
@@ -127,16 +127,16 @@ class Users {
if ( $user_id === $master_user_id && 'administrator' !== $role ) {
$query = new \WP_User_Query(
array(
- 'fields' => array( 'id' ),
+ 'fields' => array( 'ID' ),
'role' => 'administrator',
- 'orderby' => 'id',
+ 'orderby' => 'ID',
'exclude' => array( $master_user_id ),
)
);
$new_master = false;
$connection = new Jetpack_Connection();
foreach ( $query->results as $result ) {
- $found_user_id = absint( $result->id );
+ $found_user_id = absint( $result->ID );
if ( $found_user_id && $connection->is_user_connected( $found_user_id ) ) {
$new_master = $found_user_id;
break;
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-callables.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-callables.php
index 436554c9..4240744e 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-callables.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-callables.php
@@ -77,8 +77,9 @@ class Callables extends Module {
*/
const OPTION_NAMES_TO_CALLABLE_NAMES = array(
// @TODO: Audit the other option names for differences between the option names and callable names.
- 'home' => 'home_url',
- 'siteurl' => 'site_url',
+ 'home' => 'home_url',
+ 'siteurl' => 'site_url',
+ 'jetpack_active_modules' => 'active_modules',
);
/**
@@ -484,7 +485,7 @@ class Callables extends Module {
$checksum = $this->get_check_sum( $value );
// Explicitly not using Identical comparison as get_option returns a string.
- if ( ! is_null( $value ) && $this->should_send_callable( $callable_checksums, $name, $checksum ) ) {
+ if ( $value !== null && $this->should_send_callable( $callable_checksums, $name, $checksum ) ) {
// Only send callable if the non sorted checksum also does not match.
if ( $this->should_send_callable( $callable_checksums, $name, $this->get_check_sum( $value, false ) ) ) {
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-constants.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-constants.php
index d71a0fe1..db0d9ff4 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-constants.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-constants.php
@@ -198,7 +198,7 @@ class Constants extends Module {
foreach ( $constants as $name => $value ) {
$checksum = $this->get_check_sum( $value );
// Explicitly not using Identical comparison as get_option returns a string.
- if ( ! $this->still_valid_checksum( $constants_checksums, $name, $checksum ) && ! is_null( $value ) ) {
+ if ( ! $this->still_valid_checksum( $constants_checksums, $name, $checksum ) && $value !== null ) {
/**
* Tells the client to sync a constant to the server
*
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync-immediately.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync-immediately.php
index 4017df16..bee3e889 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync-immediately.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync-immediately.php
@@ -246,7 +246,10 @@ class Full_Sync_Immediately extends Module {
// Set default configuration, calculate totals, and save configuration if totals > 0.
$status = array();
foreach ( $full_sync_config as $name => $config ) {
- $module = Modules::get_module( $name );
+ $module = Modules::get_module( $name );
+ if ( ! $module ) {
+ continue;
+ }
$status[ $name ] = array(
'total' => $module->total( $config ),
'sent' => 0,
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync.php
index 0fe9245c..90121e88 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-full-sync.php
@@ -133,7 +133,7 @@ class Full_Sync extends Module {
$total_items = $module->estimate_full_sync_actions( $module_config );
// If there's information to process, configure this module.
- if ( ! is_null( $total_items ) && $total_items > 0 ) {
+ if ( $total_items !== null && $total_items > 0 ) {
$full_sync_config[ $module_name ] = $module_config;
$enqueue_status[ $module_name ] = array(
$total_items, // Total.
@@ -266,7 +266,7 @@ class Full_Sync extends Module {
$enqueue_status[ $module->name() ][2] = $next_enqueue_state;
// If items were processed, subtract them from the limit.
- if ( ! is_null( $items_enqueued ) && $items_enqueued > 0 ) {
+ if ( $items_enqueued !== null && $items_enqueued > 0 ) {
$enqueue_status[ $module->name() ][1] += $items_enqueued;
$remaining_items_to_enqueue -= $items_enqueued;
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php
index b244834f..06c06ab0 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php
@@ -205,7 +205,7 @@ class Plugins extends Module {
$plugins = get_plugins(); // Get the most up to date info.
if ( isset( $plugins[ $slug ] ) ) {
return array_merge( array( 'slug' => $slug ), $plugins[ $slug ] );
- };
+ }
// Try grabbing the info from before the update.
return isset( $this->plugins[ $slug ] ) ? array_merge( array( 'slug' => $slug ), $this->plugins[ $slug ] ) : array( 'slug' => $slug );
}
@@ -263,8 +263,8 @@ class Plugins extends Module {
return;
}
- // phpcs:ignore WordPress.Security.NonceVerification.Missing
- $plugin = $_POST['plugin'];
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
+ $plugin = wp_unslash( $_POST['plugin'] );
$plugins = get_plugins();
if ( ! isset( $plugins[ $plugin ] ) ) {
return;
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php
index b9ea21d1..5623cc2b 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-posts.php
@@ -589,7 +589,7 @@ class Posts extends Module {
* @param boolean $update Whether this is an existing post being updated or not.
*/
public function wp_insert_post( $post_ID, $post = null, $update = null ) {
- if ( ! is_numeric( $post_ID ) || is_null( $post ) ) {
+ if ( ! is_numeric( $post_ID ) || $post === null ) {
return;
}
@@ -633,7 +633,7 @@ class Posts extends Module {
* @param \WP_Post $post Post object.
**/
public function wp_after_insert_post( $post_ID, $post ) {
- if ( ! is_numeric( $post_ID ) || is_null( $post ) ) {
+ if ( ! is_numeric( $post_ID ) || $post === null ) {
return;
}
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-search.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-search.php
new file mode 100644
index 00000000..e6472c54
--- /dev/null
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-sync/src/modules/class-search.php
@@ -0,0 +1,1846 @@
+<?php
+/**
+ * Configuration lists for Jetpack Search Fields
+ *
+ * Post Meta: list of post meta keys that are available in the index
+ * and how they are configured.
+ *
+ * Custom Taxonomy: list of custom taxonomies that are indexed.
+ *
+ * The reason we need an allowed list is that Elasticsearch runs into scaling problems
+ * with more than 200k-ish total fields. The barrier to adding new fields is low,
+ * just open a PR.
+ *
+ * Although the comments indicate specific plugins, you don't need to be running
+ * that plugin for the indexing to work. The metakey just has to match.
+ *
+ * If you need a new meta key or taxonomy also consider using:
+ * jetpack-search-meta0 - jetpack-search-meta9
+ * jetpack-search-tag0 - jetpack-search-tag9
+ *
+ * @package automattic/jetpack-sync
+ */
+
+namespace Automattic\Jetpack\Sync\Modules;
+
+/**
+ * Class to handle sync for Jetpack Search.
+ */
+class Search extends Module {
+
+ /**
+ * Sync module name.
+ *
+ * @access public
+ *
+ * @return string
+ */
+ public function name() {
+ return 'search';
+ }
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ // Post meta whitelists.
+ add_filter( 'jetpack_sync_post_meta_whitelist', array( $this, 'add_search_post_meta_whitelist' ), 10 );
+ // Add options
+ add_filter( 'jetpack_sync_options_whitelist', array( $this, 'add_search_options_whitelist' ), 10 );
+ }
+
+ /**
+ * Post meta search specification.
+ *
+ * We sync and index all meta keys in this list. Additionally there are a few
+ * options.
+ *
+ * 'metakey' => [ 'searchable_in_all_content' => true ],
+ * Field will be included in the all_content fields
+ *
+ * 'metakey' => [ 'available' => false, 'alternatives' => [ 'metakey_processed' ] ],
+ * Field not in meta.* but has data in an alternative field(s) name that
+ * should work similarly. For instance, woocommerce total_sales does not go into
+ * the index, but the percentage of sales does.
+ *
+ * @static
+ * @access private
+ * @var array
+ */
+ private static $postmeta_to_sync = array(
+ // jetpack.
+ 'jetpack-search-meta0' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta1' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta2' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta3' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta4' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta5' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta6' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta7' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta8' => array( 'searchable_in_all_content' => true ),
+ 'jetpack-search-meta9' => array( 'searchable_in_all_content' => true ),
+
+ // woocommerce.
+ 'entity_types' => array(),
+ 'exclude_product_categories' => array(),
+ 'exclude_product_ids' => array(),
+ 'free_shipping' => array(),
+ 'id_field' => array(),
+ 'individual_use' => array(),
+ 'limit_usage_to_x_items' => array(),
+ 'maximum_amount' => array(),
+ 'minimum_amount' => array(),
+ 'post_id' => array(),
+ 'product_categories' => array( 'searchable_in_all_content' => true ),
+ 'product_ids' => array(),
+ 'total_sales' => array(
+ 'available' => false,
+ 'alternatives' => array(
+ 'wc.percent_of_sales',
+ ),
+ ),
+ 'usage_limit' => array(),
+ 'usage_limit_per_user' => array(),
+ '_crosssell_ids' => array(),
+ '_downloadable' => array(),
+ '_featured' => array(),
+ '_height' => array(),
+ '_length' => array(),
+ '_price' => array(
+ 'alternatives' => array(
+ 'wc.price',
+ 'wc.min_price',
+ 'wc.max_price',
+ ),
+ ),
+ '_prices_include_tax' => array(),
+ '_product_attributes' => array(),
+ '_product_version' => array(),
+ '_regular_price' => array(
+ 'alternatives' => array(
+ 'wc.regular_price',
+ ),
+ ),
+ '_sale_price' => array(
+ 'alternatives' => array(
+ 'wc.sale_price',
+ ),
+ ),
+ '_sale_price_dates_from' => array(),
+ '_sale_price_dates_to' => array(),
+ '_sku' => array( 'searchable_in_all_content' => true ),
+ '_stock_status' => array(),
+ '_wc_average_rating' => array(
+ 'alternatives' => array(
+ 'wc.ave_rating_score',
+ ),
+ ),
+ '_wc_rating_count' => array(
+ 'alternatives' => array(
+ 'wc.rating', // wc.rating.count_1, wc.rating.count_2, ...
+ ),
+ ),
+ '_wc_review_count' => array(),
+ '_weight' => array(),
+ '_width' => array(),
+
+ // co-authors plus.
+ 'cap-description' => array( 'searchable_in_all_content' => true ),
+ 'cap-user_login' => array( 'searchable_in_all_content' => true ),
+ 'cap-user_email' => array(),
+ 'cap-last_name' => array( 'searchable_in_all_content' => true ),
+ 'cap-first_name' => array( 'searchable_in_all_content' => true ),
+ 'cap-display_name' => array( 'searchable_in_all_content' => true ),
+ 'cap-website' => array(),
+ 'cap-jabber' => array(),
+ 'cap-aim' => array(),
+ 'cap-twitter' => array(),
+ 'cap-facebook' => array(),
+ 'cap-google_plus' => array(),
+ 'cap-job_title' => array( 'searchable_in_all_content' => true ),
+
+ // bbpress.
+ 'bbpl_like' => array(),
+ 'bbpress_discussion_comments_copied' => array(),
+ 'bbpress_discussion_tags_copied' => array(),
+ 'bbpress_discussion_topic_id' => array(),
+ 'bbpress_discussion_use_defaults' => array(),
+ 'bbpress_page_header_bg' => array(),
+ 'bbpress_title_bg' => array(),
+ 'use_bbpress_discussion_topic' => array(),
+
+ // wpml.
+ 'tm_meta_wpml' => array(),
+ 'wpml_language' => array(),
+ 'wpml_media_lang' => array(),
+ 'wpml_media_processed' => array(),
+
+ // blogger import.
+ 'blogger_author' => array( 'searchable_in_all_content' => true ),
+ 'blogger_blog' => array( 'searchable_in_all_content' => true ),
+ 'blogger_permalink' => array( 'searchable_in_all_content' => true ),
+
+ // geo.
+ 'geo_address' => array( 'searchable_in_all_content' => true ),
+ 'geo_latitude' => array(),
+ 'geo_longitude' => array(),
+ 'geo_public' => array(),
+ 'geolocated' => array(),
+ 'geolocation_city' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_country_long' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_country_short' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_formatted_address' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_lat' => array(),
+ 'geolocation_long' => array(),
+ 'geolocation_postcode' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_state_long' => array( 'searchable_in_all_content' => true ),
+ 'geolocation_state_short' => array( 'searchable_in_all_content' => true ),
+
+ // wp-ultimate-recipe.
+ 'recipe_alternate_image' => array(),
+ 'recipe_cook_time' => array(),
+ 'recipe_cook_time_text' => array(),
+ 'recipe_description' => array( 'searchable_in_all_content' => true ),
+ 'recipe_ingredients' => array( 'searchable_in_all_content' => true ),
+ 'recipe_instructions' => array( 'searchable_in_all_content' => true ),
+ 'recipe_notes' => array( 'searchable_in_all_content' => true ),
+ 'recipe_nutritional' => array( 'searchable_in_all_content' => true ),
+ 'recipe_passive_time' => array(),
+ 'recipe_passive_time_text' => array(),
+ 'recipe_prep_time' => array(),
+ 'recipe_prep_time_text' => array(),
+ 'recipe_rating' => array(),
+ 'recipe_servings' => array(),
+ 'recipe_servings_normalized' => array(),
+ 'recipe_servings_type' => array(),
+ 'recipe_terms' => array( 'searchable_in_all_content' => true ),
+ 'recipe_terms_with_parents' => array(),
+ 'recipe_title' => array( 'searchable_in_all_content' => true ),
+ 'recipe_user_ratings' => array(),
+ 'recipe_user_ratings_rating' => array(),
+
+ // generic fields.
+ // from advanced-custom-fields and metabox.io .
+ 'Link' => array(),
+ 'Location' => array(),
+ 'Title' => array( 'searchable_in_all_content' => true ),
+ 'ad_code' => array(),
+ 'address' => array(),
+ 'admin_mail' => array(),
+ 'admin_only' => array(),
+ 'advertisers' => array( 'searchable_in_all_content' => true ),
+ 'age' => array(),
+ 'aliases' => array(),
+ 'alternate_title' => array(),
+ 'amazon' => array(),
+ 'answer' => array( 'searchable_in_all_content' => true ),
+ 'area' => array(),
+ 'attention' => array(),
+ 'attr' => array(),
+ 'author' => array( 'searchable_in_all_content' => true ),
+ 'author_name' => array( 'searchable_in_all_content' => true ),
+ 'blog' => array(),
+ 'blog_id' => array(),
+ 'call_to_action' => array(),
+ 'campaign_preview' => array(),
+ 'canonical_url' => array(),
+ 'catch_text' => array(),
+ 'category' => array( 'searchable_in_all_content' => true ),
+ 'classificacao' => array(),
+ 'classification' => array(),
+ 'code' => array(),
+ 'codigo' => array(),
+ 'company' => array( 'searchable_in_all_content' => true ),
+ 'company_website' => array(),
+ 'config' => array(),
+ 'construction' => array(),
+ 'container_ids' => array(),
+ 'content' => array( 'searchable_in_all_content' => true ),
+ 'content_body-full_content' => array( 'searchable_in_all_content' => true ),
+ 'copyright' => array(),
+ 'custom_page_title' => array( 'searchable_in_all_content' => true ),
+ 'custom_permalink' => array(),
+ 'customize' => array(),
+ 'data' => array(),
+ 'date' => array(),
+ 'day' => array(),
+ 'descripcion' => array( 'searchable_in_all_content' => true ),
+ 'description' => array( 'searchable_in_all_content' => true ),
+ 'display_settings' => array(),
+ 'display_type' => array(),
+ 'duration' => array(),
+ 'embed' => array(),
+ 'entity_ids' => array(),
+ 'entity_types' => array(),
+ 'event_subtitle' => array( 'searchable_in_all_content' => true ),
+ 'excluded_container_ids' => array(),
+ 'exclusions' => array(),
+ 'experience' => array(),
+ 'external_url' => array(),
+ 'featured' => array(),
+ 'featured_image' => array(),
+ 'featured_post' => array(),
+ 'featured_story' => array(),
+ 'fee' => array(),
+ 'filter' => array(),
+ 'follow' => array(),
+ 'footer_text' => array(),
+ 'from_header' => array(),
+ 'fullscreen_view' => array(),
+ 'gallery' => array(),
+ 'genre' => array( 'searchable_in_all_content' => true ),
+ 'guests' => array( 'searchable_in_all_content' => true ),
+ 'has_variations' => array(),
+ 'hashtag' => array(),
+ 'header_image' => array(),
+ 'hidden_from_ui' => array(),
+ 'hide_on_screen' => array(),
+ 'homepage_order' => array(),
+ 'hours' => array(),
+ 'i18n' => array(),
+ 'id' => array(),
+ 'image' => array(),
+ 'image_size' => array(),
+ 'image_source' => array(),
+ 'index' => array(),
+ 'intro_text' => array( 'searchable_in_all_content' => true ),
+ 'job_mention' => array( 'searchable_in_all_content' => true ),
+ 'keywords' => array( 'searchable_in_all_content' => true ),
+ 'latest_news' => array(),
+ 'layout' => array(),
+ 'link' => array(),
+ 'link_dump' => array( 'searchable_in_all_content' => true ),
+ 'link_url' => array(),
+ 'location' => array(),
+ 'logo' => array(),
+ 'main_title' => array( 'searchable_in_all_content' => true ),
+ 'maximum_entity_count' => array(),
+ 'media' => array(),
+ 'mentions' => array(),
+ 'messages' => array(),
+ 'meta_description' => array( 'searchable_in_all_content' => true ),
+ 'meta_id' => array(),
+ 'meta_index' => array(),
+ 'meta_key' => array(),
+ 'meta_value' => array(),
+ 'modal-dialog-id' => array(),
+ 'name' => array( 'searchable_in_all_content' => true ),
+ 'nombre' => array( 'searchable_in_all_content' => true ),
+ 'notes' => array( 'searchable_in_all_content' => true ),
+ 'options' => array(),
+ 'order_by' => array(),
+ 'order_direction' => array(),
+ 'original_cats' => array(),
+ 'original_headers' => array(),
+ 'original_link' => array(),
+ 'original_message' => array(),
+ 'original_subject' => array(),
+ 'original_title' => array(),
+ 'original_to' => array(),
+ 'other_setting' => array(),
+ 'page_canonical' => array(),
+ 'page_layout' => array(),
+ 'page_sidebar' => array(),
+ 'page_tags' => array(),
+ 'panels_data' => array(),
+ 'parking' => array(),
+ 'pdf_upload' => array(),
+ 'photo' => array(),
+ 'play_time' => array(),
+ 'position' => array(),
+ 'post-rating' => array(),
+ 'post_background' => array(),
+ 'post_color' => array(),
+ 'post_sidebar' => array(),
+ 'post_subtitle' => array( 'searchable_in_all_content' => true ),
+ 'price' => array(),
+ 'publication' => array(),
+ 'rating' => array(),
+ 'ratings_average' => array(),
+ 'ratings_score' => array(),
+ 'ratings_users' => array(),
+ 'relation' => array(),
+ 'reply_to_header' => array(),
+ 'required' => array(),
+ 'returns' => array(),
+ 'review_post' => array(),
+ 'rule' => array(),
+ 'section' => array( 'searchable_in_all_content' => true ),
+ 'session_transcript' => array(),
+ 'settings' => array(),
+ 'sex' => array(),
+ 'shares_count' => array(),
+ 'show_description' => array( 'searchable_in_all_content' => true ),
+ 'show_page_title' => array(),
+ 'side' => array(),
+ 'sidebar' => array(),
+ 'site' => array(),
+ 'situation' => array(),
+ 'slide_template' => array(),
+ 'slug' => array(),
+ 'sortorder' => array(),
+ 'source' => array(),
+ 'start_date' => array(),
+ 'status' => array(),
+ 'styles' => array(),
+ 'subtitle' => array( 'searchable_in_all_content' => true ),
+ 'subtitulo' => array(),
+ 'success' => array(),
+ 'summary' => array( 'searchable_in_all_content' => true ),
+ 'synopsis' => array( 'searchable_in_all_content' => true ),
+ 'tel' => array(),
+ 'tema' => array(),
+ 'testimonial' => array(),
+ 'testimonial_author' => array(),
+ 'text_already_subscribed' => array(),
+ 'text_error' => array(),
+ 'text_invalid_email' => array(),
+ 'text_not_subscribed' => array(),
+ 'text_required_field_missing' => array(),
+ 'text_subscribed' => array(),
+ 'text_unsubscribed' => array(),
+ 'thumbnail' => array(),
+ 'time' => array(),
+ 'time_jump_list' => array( 'searchable_in_all_content' => true ),
+ 'title' => array( 'searchable_in_all_content' => true ),
+ 'title_view' => array(),
+ 'titre' => array( 'searchable_in_all_content' => true ),
+ 'titulo' => array( 'searchable_in_all_content' => true ),
+ 'to_header' => array(),
+ 'toc' => array(),
+ 'transcript' => array( 'searchable_in_all_content' => true ),
+ 'transport_uri' => array(),
+ 'type' => array(),
+ 'url' => array(),
+ 'validation' => array(),
+ 'value' => array(),
+ 'values' => array(),
+ 'variation' => array(),
+ 'video' => array(),
+ 'video_type' => array(),
+ 'video_url' => array(),
+ 'videopress_guid' => array(),
+ 'website' => array(),
+ 'weight' => array(),
+ 'year' => array(),
+
+ ); // end indexed post meta.
+
+ /**
+ * Postmeta being considered for indexing
+ * but currently not in the index
+ * this list is really only for documentation.
+ *
+ * @static
+ * @access private
+ * @var array
+ */
+ private static $unindexed_postmeta = array(
+
+ // Core.
+ '_wp_attached_file' => array(),
+ '_wp_attachment_context' => array(),
+ '_wp_attachment_image_alt' => array(),
+ '_wp_attachment_is_custom_header' => array(),
+ '_wp_attachment_metadata' => array(),
+ '_wp_desired_post_slug' => array(),
+ '_wp_old_date' => array(),
+ '_wp_old_slug' => array(),
+ '_wp_page_template' => array(),
+
+ // WooCommerce products.
+ // See https://github.com/woocommerce/woocommerce/blob/8ed6e7436ff87c2153ed30edd83c1ab8abbdd3e9/includes/data-stores/class-wc-product-data-store-cpt.php#L21 .
+ '_backorders' => array(),
+ '_default_attributes' => array(),
+ '_download_expiry' => array(),
+ '_download_limit' => array(),
+ '_download_permissions_granted' => array(),
+ '_downloadable_files' => array(),
+ '_file_paths' => array(),
+ '_manage_stock' => array(),
+ '_product_image_gallery' => array(),
+ '_purchase_note' => array(),
+ '_recorded_coupon_usage_counts' => array(),
+ '_recorded_sales' => array(),
+ '_sold_individually' => array(),
+ '_stock' => array(),
+ '_tax_class' => array(),
+ '_tax_status' => array(),
+ '_thumbnail_id' => array(),
+ '_upsell_ids' => array(),
+ '_variation_description' => array(),
+ '_virtual' => array(),
+ '_visibility' => array(),
+ 'coupon_amount' => array(),
+ 'default_source' => array(),
+ 'discount_type' => array(),
+ 'exclude_sale_items' => array(),
+ 'expiry_date' => array(),
+
+ // Woocommerce orders and refunds.
+ // See https://github.com/woocommerce/woocommerce/blob/8ed6e7436ff87c2153ed30edd83c1ab8abbdd3e9/includes/data-stores/class-wc-order-data-store-cpt.php#L27 .
+ // See https://github.com/woocommerce/woocommerce/blob/b8a2815ae546c836467008739e7ff5150cb08e93/includes/data-stores/class-wc-order-refund-data-store-cpt.php#L20 .
+ '_billing_address_1' => array(),
+ '_billing_address_2' => array(),
+ '_billing_address_index' => array(),
+ '_billing_city' => array(),
+ '_billing_company' => array(),
+ '_billing_country' => array(),
+ '_billing_email' => array(),
+ '_billing_first_name' => array(),
+ '_billing_last_name' => array(),
+ '_billing_phone' => array(),
+ '_billing_postcode' => array(),
+ '_billing_state' => array(),
+ '_cart_discount' => array(),
+ '_cart_discount_tax' => array(),
+ '_completed_date' => array(),
+ '_created_via' => array(),
+ '_customer_ip_address' => array(),
+ '_customer_user_agent' => array(),
+ '_date_completed' => array(),
+ '_date_paid' => array(),
+ '_order_currency' => array(),
+ '_order_key' => array(),
+ '_order_shipping' => array(),
+ '_order_shipping_tax' => array(),
+ '_order_stock_reduced' => array(),
+ '_order_tax' => array(),
+ '_order_total' => array(),
+ '_order_version' => array(),
+ '_paid_date' => array(),
+ '_payment_method' => array(),
+ '_payment_method_title' => array(),
+ '_payment_tokens' => array(),
+ '_recorded_coupon_usage_counts' => array(),
+ '_refund_amount' => array(),
+ '_refund_reason' => array(),
+ '_refunded_by' => array(),
+ '_shipping_address_1' => array(),
+ '_shipping_address_2' => array(),
+ '_shipping_address_index' => array(),
+ '_shipping_city' => array(),
+ '_shipping_company' => array(),
+ '_shipping_country' => array(),
+ '_shipping_first_name' => array(),
+ '_shipping_last_name' => array(),
+ '_shipping_postcode' => array(),
+ '_shipping_state' => array(),
+ '_transaction_id' => array(),
+
+ // aioseop.
+ '_aioseop_description' => array(),
+ '_aioseop_keywords' => array(),
+ '_aioseop_title' => array(),
+
+ // yoast.
+ '_yoast_wpseo_authorship' => array(),
+ '_yoast_wpseo_bctitle' => array(),
+ '_yoast_wpseo_canonical' => array(),
+ '_yoast_wpseo_content_score' => array(),
+ '_yoast_wpseo_focuskw' => array(),
+ '_yoast_wpseo_focuskw_text_input' => array(),
+ '_yoast_wpseo_google-plus-description' => array(),
+ '_yoast_wpseo_google-plus-image' => array(),
+ '_yoast_wpseo_linkdex' => array(),
+ '_yoast_wpseo_meta-robots-adv' => array(),
+ '_yoast_wpseo_meta-robots-nofollow' => array(),
+ '_yoast_wpseo_meta-robots-noindex' => array(),
+ '_yoast_wpseo_metadesc' => array(),
+ '_yoast_wpseo_metakeywords' => array(),
+ '_yoast_wpseo_opengraph-description' => array(),
+ '_yoast_wpseo_opengraph-image' => array(),
+ '_yoast_wpseo_opengraph-title' => array(),
+ '_yoast_wpseo_primary_byline' => array(),
+ '_yoast_wpseo_primary_category' => array(),
+ '_yoast_wpseo_primary_product_cat' => array(),
+ '_yoast_wpseo_primary_sponsor-type' => array(),
+ '_yoast_wpseo_primary_tema_category' => array(),
+ '_yoast_wpseo_primary_wpdmcategory' => array(),
+ '_yoast_wpseo_primary_wt_portfolio_category' => array(),
+ '_yoast_wpseo_redirect' => array(),
+ '_yoast_wpseo_sitemap-include' => array(),
+ '_yoast_wpseo_sitemap-prio' => array(),
+ '_yoast_wpseo_title' => array(),
+ '_yoast_wpseo_twitter-description' => array(),
+ '_yoast_wpseo_twitter-image' => array(),
+
+ // bbpress.
+ 'bbppu_read_by' => array(),
+ '_bbp_activity_id' => array(),
+ '_bbp_attachment' => array(),
+ '_bbp_attachment_upload_error' => array(),
+ '_bbp_forum_id' => array(),
+ '_bbp_forum_parent_id' => array(),
+ '_bbp_forum_subforum_count' => array(),
+ '_bbp_forum_type' => array(),
+ '_bbp_group_ids' => array(),
+ '_bbp_last_active_id' => array(),
+ '_bbp_last_active_time' => array(),
+ '_bbp_last_reply_id' => array(),
+ '_bbp_last_topic_id' => array(),
+ '_bbp_old_forum_id' => array(),
+ '_bbp_old_sticky_status' => array(),
+ '_bbp_old_topic_id' => array(),
+ '_bbp_post_id' => array(),
+ '_bbp_reply_count' => array(),
+ '_bbp_reply_is_private' => array(),
+ '_bbp_reply_to' => array(),
+ '_bbp_revision_log' => array(),
+ '_bbp_status' => array(),
+ '_bbp_sticky_topics' => array(),
+ '_bbp_topic_count' => array(),
+ '_bbp_topic_id' => array(),
+ '_bbp_total_reply_count' => array(),
+ '_bbp_total_topic_count' => array(),
+ '_bbp_voice_count' => array(),
+
+ // ???
+ '_locale' => array(),
+
+ // wp-job-manager.
+ '_job_title' => array(),
+ '_job_description' => array(),
+
+ // wpml.
+ '_wpml_media_duplicate' => array(),
+ '_wpml_media_featured' => array(),
+
+ // generic fields.
+ 'ad_clicks_count' => array(),
+ 'email' => array(),
+ 'usage_count' => array(),
+ 'user_mail' => array(),
+ 'views' => array(),
+ '_EventAllDay' => array(),
+ '_EventCost' => array(),
+ '_EventCurrencyPosition' => array(),
+ '_EventCurrencySymbol' => array(),
+ '_EventDuration' => array(),
+ '_EventEndDate' => array(),
+ '_EventEndDateUTC' => array(),
+ '_EventOrganizerID' => array(),
+ '_EventOrigin' => array(),
+ '_EventShowMap' => array(),
+ '_EventShowMapLink' => array(),
+ '_EventStartDate' => array(),
+ '_EventStartDateUTC' => array(),
+ '_EventTimezone' => array(),
+ '_EventTimezoneAbbr' => array(),
+ '_EventURL' => array(),
+ '_EventVenueID' => array(),
+ '_OrganizerEmail' => array(),
+ '_OrganizerOrganizer' => array(),
+ '_OrganizerOrigin' => array(),
+ '_OrganizerPhone' => array(),
+ '_OrganizerWebsite' => array(),
+ '_VenueAddress' => array(),
+ '_VenueCity' => array(),
+ '_VenueCountry' => array(),
+ '_VenueOrigin' => array(),
+ '_VenuePhone' => array(),
+ '_VenueProvince' => array(),
+ '_VenueShowMap' => array(),
+ '_VenueShowMapLink' => array(),
+ '_VenueState' => array(),
+ '_VenueStateProvince' => array(),
+ '_VenueURL' => array(),
+ '_VenueVenue' => array(),
+ '_VenueVenueID' => array(),
+ '_VenueZip' => array(),
+ '_default_attributes' => array(),
+ '_description' => array(),
+ '_edit_last' => array(),
+ '_feedback_all_fields' => array(),
+ '_feedback_author' => array(),
+ '_feedback_author_email' => array(),
+ '_feedback_author_url' => array(),
+ '_feedback_contact_form_url' => array(),
+ '_feedback_ip' => array(),
+ '_feedback_subject' => array(),
+ '_file_paths' => array(),
+ '_layout' => array(),
+ '_links_to' => array(),
+ '_links_to_target' => array(),
+ '_mail' => array(),
+ '_mail_2' => array(),
+ '_messages' => array(),
+ '_numero' => array(),
+ '_post_restored_from' => array(),
+ '_video_url' => array(),
+ '_website' => array(),
+
+ ); // end unindexed post meta.
+
+ /**
+ * List of indexed taxonomy slugs - VARCHAR(32)
+ *
+ * @access private
+ * @static
+ *
+ * @var array
+ */
+ private static $taxonomies_to_sync = array(
+
+ // Core.
+ 'link_category',
+ 'nav_menu',
+ 'post_format', // Special, limited to certain values.
+
+ // bbpress.
+ 'topic',
+ 'topic-tag',
+ 'topics',
+
+ // buddypress.
+ 'bp-email-type',
+ 'bp-email-type',
+ 'bp_docs_access',
+ 'bp_docs_associated_item',
+ 'bp_docs_comment_access',
+ 'bp_docs_doc_in_folder',
+ 'bp_docs_folder_in_group',
+ 'bp_docs_tag',
+ 'bp_member_type',
+
+ // co-authors plus.
+ 'author',
+
+ // events calendar plus.
+ // the events calendar.
+ 'event-categories',
+ 'event-category',
+ 'event-tag',
+ 'event-tags',
+ 'event-type',
+ 'event-venue',
+ 'event_category',
+ 'event_location',
+ 'event_organizer',
+ 'event_tag',
+ 'event_type',
+ 'event_type_2',
+ 'event_users',
+ 'events_categories',
+ 'events_category',
+ 'events_feeds',
+ 'events_tags',
+ 'tribe_events_cat',
+
+ // jetpack.
+ 'jetpack-portfolio-tag',
+ 'jetpack-portfolio-type',
+ 'jetpack-search-tag0',
+ 'jetpack-search-tag1',
+ 'jetpack-search-tag2',
+ 'jetpack-search-tag3',
+ 'jetpack-search-tag4',
+ 'jetpack-search-tag5',
+ 'jetpack-search-tag6',
+ 'jetpack-search-tag7',
+ 'jetpack-search-tag8',
+ 'jetpack-search-tag9',
+
+ // nextgen gallery.
+ 'ngg_tag',
+
+ // polylang.
+ // wpml.
+ 'language',
+ 'post_translations',
+ 'term_language',
+ 'term_translations',
+ 'translation_priority',
+
+ // woocommerce.
+ 'pa_accessory-type',
+ 'pa_actor',
+ 'pa_age',
+ 'pa_ambulance',
+ 'pa_amount',
+ 'pa_arm-roll',
+ 'pa_aspectratio',
+ 'pa_audiencerating',
+ 'pa_author',
+ 'pa_axle',
+ 'pa_battery',
+ 'pa_belakang',
+ 'pa_binding',
+ 'pa_body-type',
+ 'pa_bore-x-stroke-mm',
+ 'pa_box-cargo',
+ 'pa_brakes',
+ 'pa_brand',
+ 'pa_brands',
+ 'pa_bus',
+ 'pa_c',
+ 'pa_cabin-to-end',
+ 'pa_capacity',
+ 'pa_catalognumberlist',
+ 'pa_ce-keurmerk',
+ 'pa_chassis-front',
+ 'pa_chassis-rear',
+ 'pa_chassis-weight-kg',
+ 'pa_chip-log',
+ 'pa_clothing-size',
+ 'pa_clutch',
+ 'pa_clutch-type',
+ 'pa_collection',
+ 'pa_color',
+ 'pa_colors',
+ 'pa_colour',
+ 'pa_compactor',
+ 'pa_condition',
+ 'pa_cor',
+ 'pa_couleur',
+ 'pa_country',
+ 'pa_countryregion-of-manufacture',
+ 'pa_crane',
+ 'pa_creator',
+ 'pa_culoare',
+ 'pa_customerpackagetype',
+ 'pa_depan',
+ 'pa_depan-belakang',
+ 'pa_department',
+ 'pa_design',
+ 'pa_diameter',
+ 'pa_diameter-cakram',
+ 'pa_dimension-mm',
+ 'pa_dimensions',
+ 'pa_director',
+ 'pa_disc-diameter',
+ 'pa_drive-system',
+ 'pa_dump',
+ 'pa_ean',
+ 'pa_eanlist',
+ 'pa_edition',
+ 'pa_electric-battery',
+ 'pa_engine-model',
+ 'pa_engine-size',
+ 'pa_ethnicity',
+ 'pa_exhaust-brake',
+ 'pa_fabric',
+ 'pa_farbe',
+ 'pa_farg',
+ 'pa_farge',
+ 'pa_features',
+ 'pa_final-gear-ratio',
+ 'pa_finish',
+ 'pa_fire-fighting',
+ 'pa_fits',
+ 'pa_flat-bed',
+ 'pa_flavour',
+ 'pa_format',
+ 'pa_fragrance',
+ 'pa_frame',
+ 'pa_front',
+ 'pa_front-overhang',
+ 'pa_front-rear',
+ 'pa_front-tread',
+ 'pa_fuel-tank',
+ 'pa_fuel-type',
+ 'pa_garantie',
+ 'pa_geadviseerd-accu-type',
+ 'pa_gear-ratio',
+ 'pa_gender',
+ 'pa_genre',
+ 'pa_gewicht-exclusief-accu',
+ 'pa_gift-card-amount',
+ 'pa_grade-ability-tan-o',
+ 'pa_groesse',
+ 'pa_gtin',
+ 'pa_gvwr-gcwr',
+ 'pa_hardwareplatform',
+ 'pa_hazardousmaterialtype',
+ 'pa_height',
+ 'pa_hekmotor-of-boegmotor',
+ 'pa_helmet-size',
+ 'pa_hersteller',
+ 'pa_high-blow-tank',
+ 'pa_hoehe',
+ 'pa_inhoud',
+ 'pa_isadultproduct',
+ 'pa_isbn',
+ 'pa_iseligiblefortradein',
+ 'pa_itemdimensions',
+ 'pa_itempartnumber',
+ 'pa_kemudi-tipe',
+ 'pa_kleur',
+ 'pa_kopling-tipe',
+ 'pa_label',
+ 'pa_languages',
+ 'pa_lbs',
+ 'pa_legaldisclaimer',
+ 'pa_lengte-aansluitkabel',
+ 'pa_length',
+ 'pa_liquid-tank',
+ 'pa_location',
+ 'pa_losse-motor-complete-set',
+ 'pa_maat',
+ 'pa_main-brake',
+ 'pa_make',
+ 'pa_manufacturer',
+ 'pa_manufacturer-part-number',
+ 'pa_manufacturermaximumage',
+ 'pa_manufacturerminimumage',
+ 'pa_manufacturerpartswarrantydesc',
+ 'pa_masseinheit',
+ 'pa_material',
+ 'pa_mau-sac',
+ 'pa_maximum-power-ps-rpm',
+ 'pa_maximum-speed',
+ 'pa_maximum-torque-kgm-rpm',
+ 'pa_mediatype',
+ 'pa_megethos',
+ 'pa_merk',
+ 'pa_metal-type',
+ 'pa_min-turning-circle',
+ 'pa_mixer',
+ 'pa_model',
+ 'pa_model-tipe',
+ 'pa_model-type',
+ 'pa_modelo',
+ 'pa_mount',
+ 'pa_mpn',
+ 'pa_nicotine-strength',
+ 'pa_nos-of-cylinder',
+ 'pa_nos-of-tire',
+ 'pa_numberofdiscs',
+ 'pa_numberofitems',
+ 'pa_numberofpages',
+ 'pa_offset',
+ 'pa_open-cargo',
+ 'pa_operatingsystem',
+ 'pa_options',
+ 'pa_other-part-number',
+ 'pa_overall-height',
+ 'pa_overall-length',
+ 'pa_overall-width',
+ 'pa_overview',
+ 'pa_packagedimensions',
+ 'pa_packagequantity',
+ 'pa_pages',
+ 'pa_parking-brake',
+ 'pa_part-number',
+ 'pa_partnumber',
+ 'pa_pattern',
+ 'pa_pattern2',
+ 'pa_performa',
+ 'pa_pictureformat',
+ 'pa_pin-size',
+ 'pa_piston-displacement-cc',
+ 'pa_ploshhad',
+ 'pa_plug-type',
+ 'pa_power',
+ 'pa_product',
+ 'pa_productgroup',
+ 'pa_producttypename',
+ 'pa_publicationdate',
+ 'pa_publisher',
+ 'pa_quantity',
+ 'pa_rear',
+ 'pa_rear-overhang',
+ 'pa_rear-tread',
+ 'pa_refrigerated-box',
+ 'pa_region',
+ 'pa_regioncode',
+ 'pa_releasedate',
+ 'pa_rem-parkir',
+ 'pa_rem-pelambat',
+ 'pa_rem-utama',
+ 'pa_reverse',
+ 'pa_runningtime',
+ 'pa_scent',
+ 'pa_schachtlengte',
+ 'pa_seeds',
+ 'pa_series',
+ 'pa_setting',
+ 'pa_sex',
+ 'pa_shape',
+ 'pa_shirt-size',
+ 'pa_size',
+ 'pa_sizes',
+ 'pa_sku',
+ 'pa_sky-lift',
+ 'pa_sleeve-length',
+ 'pa_snelheidsregeling',
+ 'pa_staart',
+ 'pa_steering',
+ 'pa_steering-type',
+ 'pa_storlek',
+ 'pa_studio',
+ 'pa_stuwkracht-lbs',
+ 'pa_style',
+ 'pa_suspensions',
+ 'pa_taille',
+ 'pa_talla',
+ 'pa_tamanho',
+ 'pa_tamano',
+ 'pa_taxi',
+ 'pa_ticket-type',
+ 'pa_tire-size',
+ 'pa_total-chassis-weight',
+ 'pa_towing-truck',
+ 'pa_tradeinvalue',
+ 'pa_trailer-t-head',
+ 'pa_transmisi-tipe',
+ 'pa_transmission',
+ 'pa_transmission-type',
+ 'pa_types',
+ 'pa_ukuran',
+ 'pa_upc',
+ 'pa_upclist',
+ 'pa_variation',
+ 'pa_vehicle-carrier',
+ 'pa_vergelijkbaar-stuwkracht',
+ 'pa_vermogen',
+ 'pa_voltage',
+ 'pa_volume',
+ 'pa_warranty',
+ 'pa_weight',
+ 'pa_wheel-base',
+ 'pa_wheel-configuration',
+ 'pa_wheel-disc-size',
+ 'pa_width',
+ 'pa_zout-water-geschikt',
+ 'product',
+ 'product-category',
+ 'product_brand',
+ 'product_delivery_time',
+ 'product_delivery_times',
+ 'product_price_label',
+ 'product_sale_labels',
+ 'product_shipping_class',
+ 'product_tag',
+ 'product_type',
+ 'product_unit',
+ 'product_visibility',
+ 'products',
+
+ // wp-job-manager.
+ 'job-category',
+ 'job-location',
+ 'job-type',
+ 'job_cat',
+ 'job_category',
+ 'job_listing_category',
+ 'job_listing_label',
+ 'job_listing_region',
+ 'job_listing_tag',
+ 'job_listing_type',
+ 'job_salary',
+ 'job_tag',
+ 'job_type',
+ 'jobman_category',
+ 'jobpost_category',
+ 'jobpost_job_type',
+ 'jobpost_location',
+ 'resume_category',
+ 'resume_groups',
+ 'resume_job_type',
+ 'resume_job_type',
+ 'resume_languages',
+ 'resume_region',
+ 'resume_skill',
+ 'resume_specialities',
+
+ // generic.
+ '_resource',
+ 'acadp_categories',
+ 'acadp_locations',
+ 'action-group',
+ 'activity',
+ 'actor',
+ 'actors',
+ 'ad-group',
+ 'adace-ad-group',
+ 'adace-sponsor',
+ 'additional_features',
+ 'adv_location',
+ 'advanced_ads_groups',
+ 'advert_category',
+ 'affcoups_coupon_category',
+ 'affcoups_coupon_type',
+ 'ai_log_context',
+ 'ai_log_level',
+ 'al_product-cat',
+ 'aol_ad_category',
+ 'aol_ad_location',
+ 'aol_ad_type',
+ 'aol_application_status',
+ 'area',
+ 'article-slug',
+ 'asgarosforum-category',
+ 'asgarosforum-usergroup',
+ 'attachment_category',
+ 'attachment_tag',
+ 'atum_location',
+ 'avhec_catgroup',
+ 'bartype',
+ 'baths',
+ 'beds',
+ 'bepro_listing_types',
+ 'blog_category',
+ 'booked_custom_calendars',
+ 'brand',
+ 'brands',
+ 'business_category',
+ 'bwg_tag',
+ 'byline',
+ 'calendar_category',
+ 'calendar_feed',
+ 'calendar_type',
+ 'campaign_category',
+ 'campaign_tag',
+ 'carousel_cat',
+ 'carousels_category',
+ 'case27_job_listing_tags',
+ 'categories',
+ 'category_media',
+ 'category_portfolio',
+ 'celebrity_cat',
+ 'chapters',
+ 'chronosly_category',
+ 'city',
+ 'classified_listing_type',
+ 'client-types',
+ 'clients_groups',
+ 'cm-business-category',
+ 'cmdm_category',
+ 'cn_log_type',
+ 'coderevolution_post_source',
+ 'collection',
+ 'community',
+ 'companies',
+ 'company',
+ 'cont_category',
+ 'content_audit',
+ 'country',
+ 'course',
+ 'course-cat',
+ 'course-category',
+ 'course_cat',
+ 'course_category',
+ 'course_difficulty',
+ 'course_tag',
+ 'courses_type',
+ 'cp_campaign',
+ 'cp_recipe_category',
+ 'csco_post_featured',
+ 'ct_status',
+ 'ctl-stories',
+ 'cuisine',
+ 'dc_vendor_shop',
+ 'ddownload_category',
+ 'ddownload_tag',
+ 'dealstore',
+ 'department',
+ 'departments',
+ 'department-company',
+ 'developed-by',
+ 'dfads_group',
+ 'dgfw_gift_categories',
+ 'director',
+ 'district',
+ 'dlm_download_category',
+ 'dlm_download_tag',
+ 'doc_tag',
+ 'document-category',
+ 'download_artist',
+ 'download_category',
+ 'download_tag',
+ 'downloads_filter',
+ 'dps_book',
+ 'dt_gallery_category',
+ 'dt_logos_category',
+ 'dt_portfolio_category',
+ 'dt_team_category',
+ 'dt_testimonials_category',
+ 'dtcast',
+ 'dtcreator',
+ 'dtdirector',
+ 'dtnetworks',
+ 'dtstudio',
+ 'dtyear',
+ 'dvteamtaxonomy',
+ 'dwqa-question_category',
+ 'dwqa-question_tag',
+ 'eafl_category',
+ 'easy-testimonial-category',
+ 'ecwd_event_category',
+ 'edd_log_type',
+ 'edition',
+ 'ef_editorial_meta',
+ 'ef_usergroup',
+ 'element_category',
+ 'elementor_library_type',
+ 'employees_category',
+ 'encyclopedia-tag',
+ 'envira-tag',
+ 'epkb_post_type_1_category',
+ 'espresso_event_categories',
+ 'espresso_event_type',
+ 'essential_grid_category',
+ 'et_post_format',
+ 'faq-group',
+ 'faq-tags',
+ 'faq-topic',
+ 'faq_cat',
+ 'faq_categories',
+ 'faq_category',
+ 'faqs-category',
+ 'fdm-menu-section',
+ 'feature',
+ 'featured_item_category',
+ 'featured_item_tag',
+ 'feedback_type',
+ 'feeds',
+ 'fl-builder-template-type',
+ 'flamingo_inbound_channel',
+ 'follow_up_email_campaign',
+ 'follow_up_email_type',
+ 'following_users',
+ 'football-team-taxo',
+ 'fpd_design_category',
+ 'gallery-category',
+ 'gallery_cat',
+ 'gallery_categories',
+ 'gallery_category',
+ 'gallery_entries',
+ 'gallerycat',
+ 'gd_event_tags',
+ 'gd_eventcategory',
+ 'gd_place_tags',
+ 'gd_placecategory',
+ 'genre',
+ 'genres',
+ 'gg_connect_hub',
+ 'give_log_type',
+ 'gn-genre',
+ 'gn-location-1',
+ 'gn-location-2',
+ 'gn-location-3',
+ 'gp_hubs',
+ 'gp_portfolios',
+ 'gp_videos',
+ 'group',
+ 'group-documents-category',
+ 'groups',
+ 'hashtags',
+ 'hotel_facility',
+ 'ia_invited_groups',
+ 'ia_invitees',
+ 'incsub_wiki_category',
+ 'industry',
+ 'ingredient',
+ 'issue',
+ 'issuem_issue',
+ 'issuem_issue_tags',
+ 'jbp_category',
+ 'karma-slider-category',
+ 'klaviyo_shop_cart_status',
+ 'kwlogos-carousel',
+ 'layout_category',
+ 'layout_type',
+ 'ld_course_category',
+ 'ld_course_tag',
+ 'ld_lesson_category',
+ 'ld_lesson_tag',
+ 'ld_topic_tag',
+ 'lesson-tag',
+ 'level',
+ 'lingotek_hash',
+ 'lingotek_profile',
+ 'link_library_category',
+ 'linkage',
+ 'list-tags',
+ 'listing-category',
+ 'listing_amenities',
+ 'listing_category',
+ 'liveblog',
+ 'llms_access_plan_visibility',
+ 'llms_product_visibility',
+ 'localisation',
+ 'location',
+ 'location-tag',
+ 'locations',
+ 'magazine',
+ 'map_location_categories',
+ 'masonry_gallery_category',
+ 'mc-event-category',
+ 'mec_category',
+ 'mec_location',
+ 'mec_organizer',
+ 'media-category',
+ 'media-tags',
+ 'media_category',
+ 'media_folder',
+ 'member_cat',
+ 'mentions',
+ 'mesh_template_types',
+ 'ml-slider',
+ 'module',
+ 'module-tag',
+ 'module_width',
+ 'movie_cat',
+ 'mpp-component',
+ 'mpp-status',
+ 'mpp-type',
+ 'muvicast',
+ 'muvicountry',
+ 'muvidirector',
+ 'muviindex',
+ 'muviquality',
+ 'muviyear',
+ 'news-category',
+ 'news-tag',
+ 'news_category',
+ 'nova_menu',
+ 'nova_menu_item_label',
+ 'offer-types',
+ 'organization',
+ 'our_team_category',
+ 'page_category',
+ 'parisrestaurant',
+ 'parissauna',
+ 'partner_category',
+ 'partners',
+ 'paswdestinatari',
+ 'paypal_ipn_type',
+ 'pdf_lv_tag',
+ 'pec_events_category',
+ 'people',
+ 'people-expertise',
+ 'people-location',
+ 'perfect_quotes_category',
+ 'performer',
+ 'person',
+ 'personnal-category',
+ 'pexcontentslider_category',
+ 'pexfullslider_category',
+ 'pexnivoslider_category',
+ 'pexpricing_category',
+ 'pexservice_category',
+ 'pextestimonial_category',
+ 'pf_feed_item_tag',
+ 'pg_sas_type',
+ 'photo_tag',
+ 'phototype',
+ 'pj-categs',
+ 'pj-tags',
+ 'pl-categs',
+ 'placement',
+ 'plan_status',
+ 'platform',
+ 'player',
+ 'plugins_categories',
+ 'podcast',
+ 'pojo_sidebars',
+ 'popup_category',
+ 'pornstars',
+ 'portada',
+ 'portcat',
+ 'portfolio-category',
+ 'portfolio-gallery',
+ 'portfolio-skills',
+ 'portfolio-tag',
+ 'portfolio-tags',
+ 'portfolio-type',
+ 'portfolio-types',
+ 'portfolio_cat',
+ 'portfolio_categories',
+ 'portfolio_category',
+ 'portfolio_cats',
+ 'portfolio_client',
+ 'portfolio_entries',
+ 'portfolio_filter',
+ 'portfolio_in',
+ 'portfolio_label',
+ 'portfolio_skills',
+ 'portfolio_tag',
+ 'portfolio_tags',
+ 'portfolio_type',
+ 'posicao',
+ 'post-type',
+ 'post_format',
+ 'post_series',
+ 'pp_editorial_meta',
+ 'pp_notify_role',
+ 'pp_usergroup',
+ 'pricingcats',
+ 'print_section',
+ 'print_status',
+ 'programs',
+ 'project-attributes',
+ 'project-cat',
+ 'project-category',
+ 'project-type',
+ 'project_category',
+ 'project_tag',
+ 'projects_category',
+ 'projects_tag',
+ 'prominence',
+ 'promotion-categories',
+ 'property-city',
+ 'property-feature',
+ 'property-status',
+ 'property-type',
+ 'property-types',
+ 'property_action_category',
+ 'property_area',
+ 'property_category',
+ 'property_city',
+ 'property_feature',
+ 'property_status',
+ 'property_type',
+ 'province',
+ 'provinces',
+ 'publisher',
+ 'pwb-brand',
+ 'qmn_log_type',
+ 'qualification',
+ 'quality',
+ 'question-category',
+ 'question-tag',
+ 'question-type',
+ 'question_cat',
+ 'question_category',
+ 'question_tag',
+ 'quiz',
+ 'quiz-type',
+ 'quote_status',
+ 'rating',
+ 'reaction',
+ 'recipe-category',
+ 'recipe_category',
+ 'recipe_type',
+ 'region',
+ 'registrant-event',
+ 'related_keywords',
+ 'release-date',
+ 'resource-type',
+ 'resource_category',
+ 'resource_type',
+ 'resourcetype',
+ 'review-type',
+ 'review_category',
+ 'rodzaj',
+ 'role',
+ 'room_category',
+ 'room_tag',
+ 'roomtype',
+ 'rubriek_categorie',
+ 'savedreply',
+ 'schools',
+ 'scope',
+ 'scores_cat',
+ 'sdm_categories',
+ 'sdm_tags',
+ 'season',
+ 'secondary_html_features',
+ 'section',
+ 'sector',
+ 'series',
+ 'series_of_posts',
+ 'services_group',
+ 'serving',
+ 'shop_cart_status',
+ 'shop_cat',
+ 'shop_order_status',
+ 'shop_vendor',
+ 'shop_warranty_status',
+ 'shopp_category',
+ 'shopr_category',
+ 'show',
+ 'simple_link_category',
+ 'site-review-category',
+ 'sizes',
+ 'skill',
+ 'skill_level',
+ 'skills',
+ 'sld_cat',
+ 'slide-page',
+ 'slide-types',
+ 'slide_categories',
+ 'slide_type',
+ 'slider',
+ 'slider-locations',
+ 'slider_category',
+ 'slides_category',
+ 'slideshow',
+ 'sm-category',
+ 'snax_format',
+ 'sngg_media_tags',
+ 'solution_channel',
+ 'source_domain',
+ 'source_id',
+ 'sp_league',
+ 'sp_position',
+ 'sp_role',
+ 'sp_season',
+ 'sp_venue',
+ 'speaker',
+ 'speakers',
+ 'special-feature',
+ 'specialty',
+ 'spnl_log_type',
+ 'sponsor_categories',
+ 'sponsor_category',
+ 'sponsor_type',
+ 'spot_tag',
+ 'st_af_category',
+ 'st_af_tags',
+ 'staff',
+ 'staff-member-category',
+ 'staff-member-group',
+ 'staff_category',
+ 'staffgroups',
+ 'state',
+ 'status',
+ 'store',
+ 'stores',
+ 'studio',
+ 'study_level',
+ 'style',
+ 'style_category',
+ 'sub_transaction_action',
+ 'sub_transaction_result',
+ 'subcategory',
+ 'subject',
+ 'subscription_status',
+ 'swift-slider-category',
+ 'syn_sitegroup',
+ 'szbl-content-tag',
+ 'task-queue',
+ 'tax_feature',
+ 'tcb_symbols_tax',
+ 'tcp_product_category',
+ 'team',
+ 'team-category',
+ 'team_cat',
+ 'team_categories',
+ 'team_category',
+ 'team_cats',
+ 'team_department',
+ 'team_designation',
+ 'team_group',
+ 'team_member_position',
+ 'team_mfcategory',
+ 'teams',
+ 'tenant_categories',
+ 'tenant_location',
+ 'tender-category',
+ 'test-type',
+ 'testimonial-category',
+ 'testimonial-group',
+ 'testimonial-types',
+ 'testimonial_categories',
+ 'testimonial_category',
+ 'testimonials-category',
+ 'testimonials_category',
+ 'th_events_cat',
+ 'th_galleries_cat',
+ 'thegem_clients_sets',
+ 'thegem_news_sets',
+ 'thegem_portfolios',
+ 'thegem_quickfinders',
+ 'thegem_teams',
+ 'thegem_testimonials_sets',
+ 'theme',
+ 'themefusion_es_groups',
+ 'themes_categories',
+ 'themo_cpt_group',
+ 'themo_project_type',
+ 'themo_room_type',
+ 'thirstylink-category',
+ 'ticket_channel',
+ 'ticket_priority',
+ 'timeline_post_tag',
+ 'tipo',
+ 'tipologie',
+ 'tips',
+ 'tm-testimonials_category',
+ 'tm_testimonial_group',
+ 'tooltips_categories',
+ 'tour_category',
+ 'tour_destination',
+ 'tour_facility',
+ 'tour_phys',
+ 'tour_type',
+ 'tp_event_category',
+ 'transmission',
+ 'treatment-type',
+ 'tribe_events_cat',
+ 'truethemes-gallery-category',
+ 'tsas-category',
+ 'tshowcase-categories',
+ 'tsml_region',
+ 'ttshowcase_groups',
+ 'tvo_tags',
+ 'type',
+ 'types',
+ 'u_course_cat',
+ 'u_department',
+ 'u_event_cat',
+ 'ufaq-category',
+ 'ufaq-tag',
+ 'um_hashtag',
+ 'um_user_tag',
+ 'uncodeblock_category',
+ 'upg_cate',
+ 'urp-review-category',
+ 'us_portfolio_category',
+ 'us_testimonial_category',
+ 'user-group',
+ 'user_category',
+ 'user_status',
+ 'vendor',
+ 'venue',
+ 'video-category',
+ 'video-series',
+ 'video-tag',
+ 'video_category',
+ 'video_tag',
+ 'videos',
+ 'videos_categories',
+ 'voice_category',
+ 'vtmin_rule_category',
+ 'vtprd_rule_category',
+ 'w2dc-category',
+ 'w2dc-location',
+ 'w2dc-tag',
+ 'wcb_sponsor_level',
+ 'wcb_track',
+ 'wccf_checkout_field_field_type',
+ 'wccf_checkout_field_status',
+ 'wccf_order_field_field_type',
+ 'wccf_order_field_status',
+ 'wccf_product_field_field_type',
+ 'wccf_product_field_status',
+ 'wccf_product_prop_field_type',
+ 'wccf_product_prop_status',
+ 'wccf_user_field_field_type',
+ 'wccf_user_field_status',
+ 'wcfm_knowledgebase_category',
+ 'wcm_task_category',
+ 'wcpv_product_vendors',
+ 'wcs-instructor',
+ 'wcs-room',
+ 'wcs-type',
+ 'wdca_ad_categories',
+ 'where',
+ 'who',
+ 'wiki-category',
+ 'wiki_cats',
+ 'wl_entity_type',
+ 'workout_entries',
+ 'works-category',
+ 'wp-rest-api-log-method',
+ 'wp-rest-api-log-source',
+ 'wp-rest-api-log-status',
+ 'wp-type-activity-types',
+ 'wp-type-contacts-subtype',
+ 'wp-type-group',
+ 'wp_bannerize_tax',
+ 'wp_log_type',
+ 'wp_super_faq_category',
+ 'wpbdm-region',
+ 'wpbdp_category',
+ 'wpbdp_tag',
+ 'wpcm_make_model',
+ 'wpdmcategory',
+ 'wpfb_file_category',
+ 'wpfcas-category',
+ 'wpfd-category',
+ 'wplead_list_category',
+ 'wplss_logo_showcase_cat',
+ 'wpm-testimonial-category',
+ 'wpmf-category',
+ 'wpostahs-slider-category',
+ 'wprm_course',
+ 'wprm_cuisine',
+ 'wprm_ingredient',
+ 'wprm_keyword',
+ 'wprss_category',
+ 'wps_forum',
+ 'wpsc-variation',
+ 'wpsc_log_type',
+ 'wpsc_product_category',
+ 'wpseo_locations_category',
+ 'wpsisac_slider-category',
+ 'wpsl_store_category',
+ 'wpt_category',
+ 'wpt_result',
+ 'wpt_scale',
+ 'wpv_sermons_category',
+ 'wpvqgr_tag',
+ 'writer',
+ 'wyz_business_category',
+ 'wyz_business_rating_category',
+ 'wyz_business_tag',
+ 'wzkb_category',
+ 'year',
+ 'years',
+ 'yith_product_brand',
+ 'yith_shop_vendor',
+ 'yst_prominent_words',
+ 'zipcode',
+ 'zoninator_zones',
+ 'zrf_field_group',
+
+ // End The Backlog @see https://wp.me/p9MPsk-X0.
+ 'bill-status',
+ 'etb-audience',
+ 'etb-state',
+ 'etb-target',
+ 'etb-topic',
+ 'etb-year',
+ 'foia-response-status',
+ 'target-type',
+ 'timeline-pillar',
+ 'timeline-type',
+
+ ); // end taxonomies.
+
+ /**
+ * List of options to sync
+ *
+ * @access private
+ * @static
+ *
+ * @var array
+ */
+ private static $options_to_sync = array(
+ 'jetpack_search_color_theme',
+ 'jetpack_search_result_format',
+ 'jetpack_search_default_sort',
+ 'jetpack_search_overlay_trigger',
+ 'jetpack_search_excluded_post_types',
+ 'jetpack_search_highlight_color',
+ 'jetpack_search_enable_sort',
+ 'jetpack_search_inf_scroll',
+ 'jetpack_search_show_powered_by',
+ 'instant_search_enabled',
+ ); // end options.
+
+ /*
+ * Taxonomies we know don't sync.
+ * See also sync/src/class-defaults.php
+ *
+ * 'network'
+ * 'post_status'
+ * 'product_cat'
+ * 'tags'
+ *
+ */
+
+ //
+ // Hooks into sync.
+
+ /**
+ * Add Search post meta to the post meta whitelist.
+ *
+ * @param array $list Existing post meta whitelist.
+ * @return array Updated post meta whitelist.
+ */
+ public function add_search_post_meta_whitelist( $list ) {
+ return array_merge( $list, $this->get_all_postmeta_keys() );
+ }
+
+ /**
+ * Add Search options to the options whitelist.
+ *
+ * @param array $list Existing options whitelist.
+ * @return array Updated options whitelist.
+ */
+ public function add_search_options_whitelist( $list ) {
+ return array_merge( $list, $this->get_all_option_keys() );
+ }
+
+ //
+ // Indexing functions for wp.com.
+
+ /**
+ *
+ * Check whether a postmeta or taxonomy 'key' is in the indexable
+ * list. This is called by the indexing code on wp.com to decide
+ * whether to include something in the index.
+ *
+ * @static
+ * @access public
+ *
+ * @param string $type Either 'postmeta' or 'taxonomy'.
+ * @param string $key The postmeta key or taxonomy name.
+ * @return boolean
+ */
+ public static function is_indexable( $type, $key ) {
+ switch ( $type ) {
+ case 'postmeta':
+ return isset( self::$postmeta_to_sync[ $key ] );
+ case 'taxonomy':
+ return in_array( $key, self::$taxonomies_to_sync, true );
+ }
+ return false;
+ }
+
+ /**
+ *
+ * Get the indexing spec for a postmeta key.
+ *
+ * @static
+ * @access public
+ *
+ * @param string $key The postmeta key.
+ * @return array The spec.
+ */
+ public static function get_postmeta_spec( $key ) {
+ return self::$postmeta_to_sync[ $key ];
+ }
+
+ /**
+ * Get all post meta keys that get synced.
+ *
+ * @access public
+ *
+ * @return array List of post meta keys that get synced.
+ */
+ public static function get_all_postmeta_keys() {
+ return array_keys( self::$postmeta_to_sync );
+ }
+
+ /**
+ * Get all option keys that get synced.
+ *
+ * @access public
+ *
+ * @return array List of option keys that get synced.
+ */
+ public static function get_all_option_keys() {
+ return self::$options_to_sync;
+ }
+
+ /**
+ * Get all unindexed postmeta.
+ * This is mostly for testing.
+ *
+ * @access public
+ *
+ * @return array List of postmeta that are not synced.
+ */
+ public static function get_all_unindexed_postmeta_keys() {
+ return array_keys( self::$unindexed_postmeta );
+ }
+
+ /**
+ * Get all taxonomies that get synced.
+ * This is mostly for testing.
+ *
+ * @access public
+ *
+ * @return array List of taxonomies that get synced.
+ */
+ public static function get_all_taxonomies() {
+ return self::$taxonomies_to_sync;
+ }
+
+}