PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-sync / src / class-data-settings.php
jetpack / jetpack_vendor / automattic / jetpack-sync / src Last commit date
modules 1 month ago replicastore 4 months ago sync-queue 6 months ago class-actions.php 3 months ago class-activity-log-event.php 1 month ago class-data-settings.php 2 months ago class-dedicated-sender.php 2 days ago class-default-filter-settings.php 4 years ago class-defaults.php 1 month ago class-functions.php 2 months ago class-health.php 5 months ago class-json-deflate-array-codec.php 8 months ago class-listener.php 2 months ago class-lock.php 4 years ago class-main.php 3 months ago class-modules.php 2 years ago class-package-version.php 2 days ago class-queue-buffer.php 4 years ago class-queue.php 2 months ago class-replicastore.php 2 months ago class-rest-endpoints.php 5 months ago class-rest-sender.php 2 months ago class-sender.php 2 months ago class-server.php 5 months ago class-settings.php 4 months ago class-simple-codec.php 8 months ago class-users.php 4 months ago class-utils.php 4 years ago interface-codec.php 4 years ago interface-replicastore.php 2 months ago
class-data-settings.php
420 lines
1 <?php
2 /**
3 * The Data Settings class.
4 *
5 * @package automattic/jetpack-sync
6 */
7
8 namespace Automattic\Jetpack\Sync;
9
10 /**
11 * The Data_Settings class
12 */
13 class Data_Settings {
14
15 /**
16 * The data that must be synced for every synced site.
17 */
18 const MUST_SYNC_DATA_SETTINGS = array(
19 'jetpack_sync_modules' => array(
20 'Automattic\\Jetpack\\Sync\\Modules\\Callables',
21 'Automattic\\Jetpack\\Sync\\Modules\\Constants',
22 'Automattic\\Jetpack\\Sync\\Modules\\Full_Sync_Immediately', // enable Initial Sync on Site Connection.
23 'Automattic\\Jetpack\\Sync\\Modules\\Options',
24 'Automattic\\Jetpack\\Sync\\Modules\\Updates',
25 'Automattic\\Jetpack\\Sync\\Modules\\Stats', // Daily heartbeat data.
26 ),
27 'jetpack_sync_callable_whitelist' => array(
28 'site_url' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'site_url' ),
29 'home_url' => array( 'Automattic\\Jetpack\\Connection\\Urls', 'home_url' ),
30 'get_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_plugins' ),
31 'get_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_themes' ),
32 'jetpack_connection_active_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_jetpack_connection_active_plugins' ),
33 'jetpack_package_versions' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_jetpack_package_versions' ),
34 'paused_plugins' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_plugins' ),
35 'paused_themes' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_paused_themes' ),
36 'timezone' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_timezone' ),
37 'wp_get_environment_type' => 'wp_get_environment_type',
38 'wp_max_upload_size' => 'wp_max_upload_size',
39 'wp_version' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'wp_version' ),
40 'jetpack_sync_active_modules' => array( 'Automattic\\Jetpack\\Sync\\Functions', 'get_jetpack_sync_active_modules' ),
41 ),
42 'jetpack_sync_constants_whitelist' => array(
43 'ABSPATH',
44 'ALTERNATE_WP_CRON',
45 'ATOMIC_CLIENT_ID',
46 'AUTOMATIC_UPDATER_DISABLED',
47 'DISABLE_WP_CRON',
48 'DISALLOW_FILE_EDIT',
49 'DISALLOW_FILE_MODS',
50 'EMPTY_TRASH_DAYS',
51 'FS_METHOD',
52 'IS_PRESSABLE',
53 'PHP_VERSION',
54 'WP_ACCESSIBLE_HOSTS',
55 'WP_AUTO_UPDATE_CORE',
56 'WP_CONTENT_DIR',
57 'WP_CRON_LOCK_TIMEOUT',
58 'WP_DEBUG',
59 'WP_HTTP_BLOCK_EXTERNAL',
60 'WP_MAX_MEMORY_LIMIT',
61 'WP_MEMORY_LIMIT',
62 'WP_POST_REVISIONS',
63 ),
64 'jetpack_sync_options_whitelist' => array(
65 /**
66 * Sync related options
67 */
68 'jetpack_sync_non_blocking',
69 'jetpack_sync_non_public_post_stati',
70 'jetpack_sync_settings_comment_meta_whitelist',
71 'jetpack_sync_settings_post_meta_whitelist',
72 'jetpack_sync_settings_post_types_blacklist',
73 'jetpack_sync_settings_taxonomies_blacklist',
74 'jetpack_sync_settings_dedicated_sync_enabled',
75 'jetpack_sync_settings_custom_queue_table_enabled',
76 'jetpack_sync_settings_wpcom_rest_api_enabled',
77 /**
78 * Generic site options
79 */
80 'blog_charset',
81 'blog_public',
82 'blogdescription',
83 'blogname',
84 'permalink_structure',
85 'stylesheet',
86 'time_format',
87 'timezone_string',
88 'active_plugins',
89 ),
90 );
91
92 const MODULE_FILTER_MAPPING = array(
93 'Automattic\\Jetpack\\Sync\\Modules\\Options' => array(
94 'jetpack_sync_options_whitelist',
95 'jetpack_sync_options_contentless',
96 ),
97 'Automattic\\Jetpack\\Sync\\Modules\\Constants' => array(
98 'jetpack_sync_constants_whitelist',
99 ),
100 'Automattic\\Jetpack\\Sync\\Modules\\Callables' => array(
101 'jetpack_sync_callable_whitelist',
102 'jetpack_sync_multisite_callable_whitelist',
103 ),
104 'Automattic\\Jetpack\\Sync\\Modules\\Posts' => array(
105 'jetpack_sync_post_meta_whitelist',
106 ),
107 'Automattic\\Jetpack\\Sync\\Modules\\Comments' => array(
108 'jetpack_sync_comment_meta_whitelist',
109 ),
110 'Automattic\\Jetpack\\Sync\\Modules\\Users' => array(
111 'jetpack_sync_capabilities_whitelist',
112 ),
113 'Automattic\\Jetpack\\Sync\\Modules\\Import' => array(
114 'jetpack_sync_known_importers',
115 ),
116 );
117
118 const MODULES_FILTER_NAME = 'jetpack_sync_modules';
119
120 /**
121 * The static data settings array which contains the aggregated data settings for
122 * each sync filter.
123 *
124 * @var array
125 */
126 private static $data_settings = array();
127
128 /**
129 * The static array which contains the list of filter hooks that have already been set up.
130 *
131 * @var array
132 */
133 private static $set_filter_hooks = array();
134
135 /**
136 * Adds the data settings provided by a plugin to the Sync data settings.
137 *
138 * @param array $plugin_settings The array provided by the plugin. The array must use filters
139 * from the DATA_FILTER_DEFAULTS list as keys.
140 */
141 public function add_settings_list( $plugin_settings = array() ) {
142 if ( empty( $plugin_settings ) || ! is_array( $plugin_settings ) ) {
143 /*
144 * No custom plugin settings, so use defaults for everything and bail early.
145 */
146 $this->set_all_defaults();
147 return;
148 }
149
150 $this->add_filters_custom_settings_and_hooks( $plugin_settings );
151
152 if ( ! did_action( 'jetpack_sync_add_required_data_settings' ) ) {
153 $this->add_required_settings();
154 /**
155 * Fires when the required settings have been adding to the static
156 * data_settings array.
157 *
158 * @since 1.29.2
159 *
160 * @module sync
161 */
162 do_action( 'jetpack_sync_add_required_data_settings' );
163 }
164 }
165
166 /**
167 * Sets the default values for sync modules and all sync data filters.
168 */
169 private function set_all_defaults() {
170 $this->add_sync_filter_setting( self::MODULES_FILTER_NAME, Modules::DEFAULT_SYNC_MODULES );
171
172 foreach ( array_keys( Default_Filter_Settings::DATA_FILTER_DEFAULTS ) as $filter ) {
173 $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
174 }
175 }
176
177 /**
178 * Returns the default settings for the given filter.
179 *
180 * @param string $filter The filter name.
181 *
182 * @return array The filter's default settings array.
183 */
184 private function get_default_setting_for_filter( $filter ) {
185 if ( self::MODULES_FILTER_NAME === $filter ) {
186 return Modules::DEFAULT_SYNC_MODULES;
187 }
188
189 return ( new Default_Filter_Settings() )->get_default_settings( $filter );
190 }
191
192 /**
193 * Adds the custom settings and sets up the necessary filter hooks.
194 *
195 * @param array $filters_settings The custom settings.
196 */
197 private function add_filters_custom_settings_and_hooks( $filters_settings ) {
198 if ( isset( $filters_settings[ self::MODULES_FILTER_NAME ] ) && is_array( $filters_settings[ self::MODULES_FILTER_NAME ] ) ) {
199 $this->add_custom_filter_setting( self::MODULES_FILTER_NAME, $filters_settings[ self::MODULES_FILTER_NAME ] );
200 $enabled_modules = $filters_settings[ self::MODULES_FILTER_NAME ];
201 } else {
202 $this->add_sync_filter_setting( self::MODULES_FILTER_NAME, Modules::DEFAULT_SYNC_MODULES );
203 $enabled_modules = Modules::DEFAULT_SYNC_MODULES;
204 }
205
206 $all_modules = Modules::DEFAULT_SYNC_MODULES;
207
208 foreach ( $all_modules as $module ) {
209 if ( in_array( $module, $enabled_modules, true ) || in_array( $module, self::MUST_SYNC_DATA_SETTINGS['jetpack_sync_modules'], true ) ) {
210 $this->add_filters_for_enabled_module( $module, $filters_settings );
211 } else {
212 $this->add_filters_for_disabled_module( $module );
213 }
214 }
215 }
216
217 /**
218 * Adds the filters for the provided enabled module. If the settings provided custom filter settings
219 * for the module's filters, those are used. Otherwise, the filter's default settings are used.
220 *
221 * @param string $module The module name.
222 * @param array $filters_settings The settings for the filters.
223 */
224 private function add_filters_for_enabled_module( $module, $filters_settings ) {
225 $module_mapping = self::MODULE_FILTER_MAPPING;
226 $filters_for_module = $module_mapping[ $module ] ?? array();
227
228 foreach ( $filters_for_module as $filter ) {
229 if ( isset( $filters_settings[ $filter ] ) ) {
230 $this->add_custom_filter_setting( $filter, $filters_settings[ $filter ] );
231 } else {
232 $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
233 }
234 }
235 }
236
237 /**
238 * Adds the filters for the provided disabled module. The disabled module's associated filter settings are
239 * set to an empty array.
240 *
241 * @param string $module The module name.
242 */
243 private function add_filters_for_disabled_module( $module ) {
244 $module_mapping = self::MODULE_FILTER_MAPPING;
245 $filters_for_module = $module_mapping[ $module ] ?? array();
246
247 foreach ( $filters_for_module as $filter ) {
248 $this->add_custom_filter_setting( $filter, array() );
249 }
250 }
251
252 /**
253 * Adds the provided custom setting for a filter. If the filter setting isn't valid, the default
254 * value is used.
255 *
256 * If the filter's hook hasn't already been set up, it gets set up.
257 *
258 * @param string $filter The filter.
259 * @param array $setting The filter setting.
260 */
261 private function add_custom_filter_setting( $filter, $setting ) {
262 if ( ! $this->is_valid_filter_setting( $filter, $setting ) ) {
263 /*
264 * The provided setting isn't valid, so use the default for this filter.
265 * We're using the default values so there's no need to set the filter hook.
266 */
267 $this->add_sync_filter_setting( $filter, $this->get_default_setting_for_filter( $filter ) );
268 return;
269 }
270
271 if ( ! isset( static::$set_filter_hooks[ $filter ] ) ) {
272 // First time a custom modules setting is provided, so set the filter hook.
273 add_filter( $filter, array( $this, 'sync_data_filter_hook' ) );
274 static::$set_filter_hooks[ $filter ] = 1;
275 }
276
277 $this->add_sync_filter_setting( $filter, $setting );
278 }
279
280 /**
281 * Determines whether the filter setting is valid. The setting array is in the correct format (associative or indexed).
282 *
283 * @param string $filter The filter to check.
284 * @param array $filter_settings The filter settings.
285 *
286 * @return bool Whether the filter settings can be used.
287 */
288 private function is_valid_filter_setting( $filter, $filter_settings ) {
289 if ( ! is_array( $filter_settings ) ) {
290 // The settings for each filter must be an array.
291 return false;
292 }
293
294 if ( empty( $filter_settings ) ) {
295 // Empty settings are allowed.
296 return true;
297 }
298
299 $indexed_array = isset( $filter_settings[0] );
300 if ( in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) && ! $indexed_array ) {
301 return true;
302 } elseif ( ! in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) && $indexed_array ) {
303 return true;
304 }
305
306 return false;
307 }
308
309 /**
310 * Adds the data settings that are always required for every plugin that uses Sync.
311 */
312 private function add_required_settings() {
313 foreach ( self::MUST_SYNC_DATA_SETTINGS as $filter => $setting ) {
314 // If the corresponding setting is already set and matches the default one, no need to proceed.
315 if ( isset( static::$data_settings[ $filter ] ) && static::$data_settings[ $filter ] === $this->get_default_setting_for_filter( $filter ) ) {
316 continue;
317 }
318 $this->add_custom_filter_setting( $filter, $setting );
319 }
320 }
321
322 /**
323 * Adds the provided data setting for the provided filter.
324 *
325 * @param string $filter The filter name.
326 * @param array $value The data setting.
327 */
328 private function add_sync_filter_setting( $filter, $value ) {
329 if ( ! isset( static::$data_settings[ $filter ] ) ) {
330 static::$data_settings[ $filter ] = $value;
331 return;
332 }
333
334 if ( in_array( $filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) ) {
335 $this->add_associative_filter_setting( $filter, $value );
336 } else {
337 $this->add_indexed_filter_setting( $filter, $value );
338 }
339 }
340
341 /**
342 * Adds the provided data setting for the provided filter. This method handles
343 * adding settings to data that is stored as an associative array.
344 *
345 * @param string $filter The filter name.
346 * @param array $settings The data settings.
347 */
348 private function add_associative_filter_setting( $filter, $settings ) {
349 foreach ( $settings as $key => $item ) {
350 if ( ! array_key_exists( $key, static::$data_settings[ $filter ] ) ) {
351 static::$data_settings[ $filter ][ $key ] = $item;
352 }
353 }
354 }
355
356 /**
357 * Adds the provided data setting for the provided filter. This method handles
358 * adding settings to data that is stored as an indexed array.
359 *
360 * @param string $filter The filter name.
361 * @param array $settings The data settings.
362 */
363 private function add_indexed_filter_setting( $filter, $settings ) {
364 static::$data_settings[ $filter ] = array_unique(
365 array_merge(
366 static::$data_settings[ $filter ],
367 $settings
368 )
369 );
370 }
371
372 /**
373 * The callback function added to the sync data filters. Combines the list in the $data_settings property
374 * with any non-default values from the received array.
375 *
376 * @param array $filtered_values The data revieved from the filter.
377 *
378 * @return array The data settings for the filter.
379 */
380 public function sync_data_filter_hook( $filtered_values ) {
381 if ( ! is_array( $filtered_values ) ) {
382 // Something is wrong with the input, so set it to an empty array.
383 $filtered_values = array();
384 }
385
386 $current_filter = current_filter();
387
388 if ( ! isset( static::$data_settings[ $current_filter ] ) ) {
389 return $filtered_values;
390 }
391
392 if ( in_array( $current_filter, Default_Filter_Settings::ASSOCIATIVE_FILTERS, true ) ) {
393 $extra_filters = array_diff_key( $filtered_values, $this->get_default_setting_for_filter( $current_filter ) );
394 $this->add_associative_filter_setting( $current_filter, $extra_filters );
395 return static::$data_settings[ $current_filter ];
396 }
397
398 $extra_filters = array_diff( $filtered_values, $this->get_default_setting_for_filter( $current_filter ) );
399 $this->add_indexed_filter_setting( $current_filter, $extra_filters );
400 return static::$data_settings[ $current_filter ];
401 }
402
403 /**
404 * Sets the $data_settings property to an empty array. This is useful for testing.
405 */
406 public function empty_data_settings_and_hooks() {
407 static::$data_settings = array();
408 static::$set_filter_hooks = array();
409 }
410
411 /**
412 * Returns the $data_settings property.
413 *
414 * @return array The data_settings property.
415 */
416 public function get_data_settings() {
417 return static::$data_settings;
418 }
419 }
420