← All changes
|
jetpack_vendor/automattic/jetpack-sync/src/class-functions.php
+782
-0
16.2-beta
→
16.3
View file →
| @@ -1,0 +1,782 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Utility functions to generate data synced to wpcom | |
| 4 | + * | |
| 5 | + * @package automattic/jetpack-sync | |
| 6 | + */ | |
| 7 | + | |
| 8 | +namespace Automattic\Jetpack\Sync; | |
| 9 | + | |
| 10 | +use Automattic\Jetpack\Connection\Manager; | |
| 11 | +use Automattic\Jetpack\Connection\Urls; | |
| 12 | +use Automattic\Jetpack\Constants; | |
| 13 | +use Automattic\Jetpack\Modules as Jetpack_Modules; | |
| 14 | +use Automattic\Jetpack\Status; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Utility functions to generate data synced to wpcom | |
| 18 | + */ | |
| 19 | +class Functions { | |
| 20 | + const HTTPS_CHECK_OPTION_PREFIX = 'jetpack_sync_https_history_'; | |
| 21 | + const HTTPS_CHECK_HISTORY = 5; | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * Return array of Jetpack modules. | |
| 25 | + * | |
| 26 | + * @return array | |
| 27 | + */ | |
| 28 | + public static function get_modules() { | |
| 29 | + if ( defined( 'JETPACK__PLUGIN_DIR' ) ) { | |
| 30 | + require_once JETPACK__PLUGIN_DIR . 'class.jetpack-admin.php'; | |
| 31 | + | |
| 32 | + return \Jetpack_Admin::init()->get_modules(); | |
| 33 | + } | |
| 34 | + | |
| 35 | + return array(); | |
| 36 | + } | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Return array of taxonomies registered on the site. | |
| 40 | + * | |
| 41 | + * @return array | |
| 42 | + */ | |
| 43 | + public static function get_taxonomies() { | |
| 44 | + global $wp_taxonomies; | |
| 45 | + $wp_taxonomies_without_callbacks = array(); | |
| 46 | + foreach ( $wp_taxonomies as $taxonomy_name => $taxonomy ) { | |
| 47 | + $sanitized_taxonomy = self::sanitize_taxonomy( $taxonomy ); | |
| 48 | + if ( ! empty( $sanitized_taxonomy ) ) { | |
| 49 | + $wp_taxonomies_without_callbacks[ $taxonomy_name ] = $sanitized_taxonomy; | |
| 50 | + } | |
| 51 | + } | |
| 52 | + return $wp_taxonomies_without_callbacks; | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Return array of registered shortcodes. | |
| 57 | + * | |
| 58 | + * @return array | |
| 59 | + */ | |
| 60 | + public static function get_shortcodes() { | |
| 61 | + global $shortcode_tags; | |
| 62 | + return array_keys( $shortcode_tags ); | |
| 63 | + } | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * Removes any callback data since we will not be able to process it on our side anyways. | |
| 67 | + * | |
| 68 | + * @param \WP_Taxonomy $taxonomy \WP_Taxonomy item. | |
| 69 | + * | |
| 70 | + * @return mixed|null | |
| 71 | + */ | |
| 72 | + public static function sanitize_taxonomy( $taxonomy ) { | |
| 73 | + | |
| 74 | + // Lets clone the taxonomy object instead of modifing the global one. | |
| 75 | + $cloned_taxonomy = json_decode( wp_json_encode( $taxonomy, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ); | |
| 76 | + | |
| 77 | + // recursive taxonomies are no fun. | |
| 78 | + if ( $cloned_taxonomy === null ) { | |
| 79 | + return null; | |
| 80 | + } | |
| 81 | + // Remove any meta_box_cb if they are not the default wp ones. | |
| 82 | + if ( isset( $cloned_taxonomy->meta_box_cb ) && | |
| 83 | + ! in_array( $cloned_taxonomy->meta_box_cb, array( 'post_tags_meta_box', 'post_categories_meta_box' ), true ) ) { | |
| 84 | + $cloned_taxonomy->meta_box_cb = null; | |
| 85 | + } | |
| 86 | + // Remove update call back. | |
| 87 | + if ( isset( $cloned_taxonomy->update_count_callback ) && | |
| 88 | + $cloned_taxonomy->update_count_callback !== null ) { | |
| 89 | + $cloned_taxonomy->update_count_callback = null; | |
| 90 | + } | |
| 91 | + // Remove rest_controller_class if it something other then the default. | |
| 92 | + if ( isset( $cloned_taxonomy->rest_controller_class ) && | |
| 93 | + 'WP_REST_Terms_Controller' !== $cloned_taxonomy->rest_controller_class ) { | |
| 94 | + $cloned_taxonomy->rest_controller_class = null; | |
| 95 | + } | |
| 96 | + return $cloned_taxonomy; | |
| 97 | + } | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Return array of registered post types. | |
| 101 | + * | |
| 102 | + * @return array | |
| 103 | + */ | |
| 104 | + public static function get_post_types() { | |
| 105 | + global $wp_post_types; | |
| 106 | + | |
| 107 | + $post_types_without_callbacks = array(); | |
| 108 | + foreach ( $wp_post_types as $post_type_name => $post_type ) { | |
| 109 | + $sanitized_post_type = self::sanitize_post_type( $post_type ); | |
| 110 | + if ( ! empty( $sanitized_post_type ) ) { | |
| 111 | + $post_types_without_callbacks[ $post_type_name ] = $sanitized_post_type; | |
| 112 | + } | |
| 113 | + } | |
| 114 | + return $post_types_without_callbacks; | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * Sanitizes by cloning post type object. | |
| 119 | + * | |
| 120 | + * @param object $post_type \WP_Post_Type. | |
| 121 | + * | |
| 122 | + * @return object | |
| 123 | + */ | |
| 124 | + public static function sanitize_post_type( $post_type ) { | |
| 125 | + // Lets clone the post type object instead of modifing the global one. | |
| 126 | + $sanitized_post_type = array(); | |
| 127 | + foreach ( Defaults::$default_post_type_attributes as $attribute_key => $default_value ) { | |
| 128 | + if ( isset( $post_type->{ $attribute_key } ) ) { | |
| 129 | + $sanitized_post_type[ $attribute_key ] = $post_type->{ $attribute_key }; | |
| 130 | + } | |
| 131 | + } | |
| 132 | + return (object) $sanitized_post_type; | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 136 | + * Return information about a synced post type. | |
| 137 | + * | |
| 138 | + * @param array $sanitized_post_type Array of args used in constructing \WP_Post_Type. | |
| 139 | + * @param string $post_type Post type name. | |
| 140 | + * | |
| 141 | + * @return object \WP_Post_Type | |
| 142 | + */ | |
| 143 | + public static function expand_synced_post_type( $sanitized_post_type, $post_type ) { | |
| 144 | + $post_type = sanitize_key( $post_type ); | |
| 145 | + $post_type_object = new \WP_Post_Type( $post_type, $sanitized_post_type ); | |
| 146 | + $post_type_object->add_supports(); | |
| 147 | + $post_type_object->add_rewrite_rules(); | |
| 148 | + $post_type_object->add_hooks(); | |
| 149 | + $post_type_object->register_taxonomies(); | |
| 150 | + return $post_type_object; | |
| 151 | + } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * Returns site's post_type_features. | |
| 155 | + * | |
| 156 | + * @return array | |
| 157 | + */ | |
| 158 | + public static function get_post_type_features() { | |
| 159 | + global $_wp_post_type_features; | |
| 160 | + | |
| 161 | + return $_wp_post_type_features; | |
| 162 | + } | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * Return hosting provider. | |
| 166 | + * | |
| 167 | + * Uses a set of known constants, classes, or functions to help determine the hosting platform. | |
| 168 | + * | |
| 169 | + * @return string Hosting provider. | |
| 170 | + */ | |
| 171 | + public static function get_hosting_provider() { | |
| 172 | + $hosting_provider_detection_methods = array( | |
| 173 | + 'get_hosting_provider_by_known_constant', | |
| 174 | + 'get_hosting_provider_by_known_class', | |
| 175 | + 'get_hosting_provider_by_known_function', | |
| 176 | + ); | |
| 177 | + | |
| 178 | + $functions = new Functions(); | |
| 179 | + foreach ( $hosting_provider_detection_methods as $method ) { | |
| 180 | + $hosting_provider = call_user_func( array( $functions, $method ) ); | |
| 181 | + if ( false !== $hosting_provider ) { | |
| 182 | + return $hosting_provider; | |
| 183 | + } | |
| 184 | + } | |
| 185 | + | |
| 186 | + return 'unknown'; | |
| 187 | + } | |
| 188 | + | |
| 189 | + /** | |
| 190 | + * Return a hosting provider using a set of known constants. | |
| 191 | + * | |
| 192 | + * @return mixed A host identifier string or false. | |
| 193 | + */ | |
| 194 | + public function get_hosting_provider_by_known_constant() { | |
| 195 | + $hosting_provider_constants = array( | |
| 196 | + 'GD_SYSTEM_PLUGIN_DIR' => 'gd-managed-wp', | |
| 197 | + 'MM_BASE_DIR' => 'bh', | |
| 198 | + 'PAGELYBIN' => 'pagely', | |
| 199 | + 'KINSTAMU_VERSION' => 'kinsta', | |
| 200 | + 'FLYWHEEL_CONFIG_DIR' => 'flywheel', | |
| 201 | + 'IS_PRESSABLE' => 'pressable', | |
| 202 | + 'VIP_GO_ENV' => 'vip-go', | |
| 203 | + ); | |
| 204 | + | |
| 205 | + foreach ( $hosting_provider_constants as $constant => $constant_value ) { | |
| 206 | + if ( Constants::is_defined( $constant ) ) { | |
| 207 | + if ( 'VIP_GO_ENV' === $constant && false === Constants::get_constant( 'VIP_GO_ENV' ) ) { | |
| 208 | + continue; | |
| 209 | + } | |
| 210 | + return $constant_value; | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 214 | + return false; | |
| 215 | + } | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Return a hosting provider using a set of known classes. | |
| 219 | + * | |
| 220 | + * @return mixed A host identifier string or false. | |
| 221 | + */ | |
| 222 | + public function get_hosting_provider_by_known_class() { | |
| 223 | + $hosting_provider = false; | |
| 224 | + | |
| 225 | + switch ( true ) { | |
| 226 | + case ( class_exists( '\\WPaaS\\Plugin' ) ): | |
| 227 | + $hosting_provider = 'gd-managed-wp'; | |
| 228 | + break; | |
| 229 | + } | |
| 230 | + | |
| 231 | + return $hosting_provider; | |
| 232 | + } | |
| 233 | + | |
| 234 | + /** | |
| 235 | + * Return a hosting provider using a set of known functions. | |
| 236 | + * | |
| 237 | + * @return mixed A host identifier string or false. | |
| 238 | + */ | |
| 239 | + public function get_hosting_provider_by_known_function() { | |
| 240 | + $hosting_provider = false; | |
| 241 | + | |
| 242 | + switch ( true ) { | |
| 243 | + case ( function_exists( 'is_wpe' ) || function_exists( 'is_wpe_snapshot' ) ): | |
| 244 | + $hosting_provider = 'wpe'; | |
| 245 | + break; | |
| 246 | + } | |
| 247 | + | |
| 248 | + return $hosting_provider; | |
| 249 | + } | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * Return array of allowed REST API post types. | |
| 253 | + * | |
| 254 | + * @return array Array of allowed post types. | |
| 255 | + */ | |
| 256 | + public static function rest_api_allowed_post_types() { | |
| 257 | + /** This filter is already documented in class.json-api-endpoints.php */ | |
| 258 | + return apply_filters( 'rest_api_allowed_post_types', array( 'post', 'page', 'revision' ) ); | |
| 259 | + } | |
| 260 | + | |
| 261 | + /** | |
| 262 | + * Return array of allowed REST API public metadata. | |
| 263 | + * | |
| 264 | + * @return array Array of allowed metadata. | |
| 265 | + */ | |
| 266 | + public static function rest_api_allowed_public_metadata() { | |
| 267 | + /** | |
| 268 | + * Filters the meta keys accessible by the REST API. | |
| 269 | + * | |
| 270 | + * @see https://developer.wordpress.com/2013/04/26/custom-post-type-and-metadata-support-in-the-rest-api/ | |
| 271 | + * | |
| 272 | + * @module json-api | |
| 273 | + * | |
| 274 | + * @since 1.6.3 | |
| 275 | + * @since-jetpack 2.2.3 | |
| 276 | + * | |
| 277 | + * @param array $whitelisted_meta Array of metadata that is accessible by the REST API. | |
| 278 | + */ | |
| 279 | + return apply_filters( 'rest_api_allowed_public_metadata', array() ); | |
| 280 | + } | |
| 281 | + | |
| 282 | + /** | |
| 283 | + * Finds out if a site is using a version control system. | |
| 284 | + * | |
| 285 | + * @return bool | |
| 286 | + **/ | |
| 287 | + public static function is_version_controlled() { | |
| 288 | + | |
| 289 | + if ( ! class_exists( 'WP_Automatic_Updater' ) ) { | |
| 290 | + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; | |
| 291 | + } | |
| 292 | + $updater = new \WP_Automatic_Updater(); | |
| 293 | + | |
| 294 | + return (bool) (string) $updater->is_vcs_checkout( ABSPATH ); | |
| 295 | + } | |
| 296 | + | |
| 297 | + /** | |
| 298 | + * Returns true if the site has file write access false otherwise. | |
| 299 | + * | |
| 300 | + * @return bool | |
| 301 | + **/ | |
| 302 | + public static function file_system_write_access() { | |
| 303 | + if ( ! function_exists( 'get_filesystem_method' ) ) { | |
| 304 | + require_once ABSPATH . 'wp-admin/includes/file.php'; | |
| 305 | + } | |
| 306 | + | |
| 307 | + require_once ABSPATH . 'wp-admin/includes/template.php'; | |
| 308 | + | |
| 309 | + $filesystem_method = get_filesystem_method(); | |
| 310 | + if ( 'direct' === $filesystem_method ) { | |
| 311 | + return true; | |
| 312 | + } | |
| 313 | + | |
| 314 | + ob_start(); | |
| 315 | + | |
| 316 | + if ( ! function_exists( 'request_filesystem_credentials' ) ) { | |
| 317 | + require_once ABSPATH . 'wp-admin/includes/file.php'; | |
| 318 | + } | |
| 319 | + | |
| 320 | + $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); | |
| 321 | + ob_end_clean(); | |
| 322 | + if ( $filesystem_credentials_are_stored ) { | |
| 323 | + return true; | |
| 324 | + } | |
| 325 | + | |
| 326 | + return false; | |
| 327 | + } | |
| 328 | + | |
| 329 | + /** | |
| 330 | + * Helper function that is used when getting home or siteurl values. Decides | |
| 331 | + * whether to get the raw or filtered value. | |
| 332 | + * | |
| 333 | + * @deprecated 1.23.1 | |
| 334 | + * | |
| 335 | + * @param string $url_type URL to get, home or siteurl. | |
| 336 | + * @return string | |
| 337 | + */ | |
| 338 | + public static function get_raw_or_filtered_url( $url_type ) { | |
| 339 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::get_raw_or_filtered_url' ); | |
| 340 | + return Urls::get_raw_or_filtered_url( $url_type ); | |
| 341 | + } | |
| 342 | + | |
| 343 | + /** | |
| 344 | + * Return the escaped home_url. | |
| 345 | + * | |
| 346 | + * @deprecated 1.23.1 | |
| 347 | + * | |
| 348 | + * @return string | |
| 349 | + */ | |
| 350 | + public static function home_url() { | |
| 351 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::home_url' ); | |
| 352 | + return Urls::home_url(); | |
| 353 | + } | |
| 354 | + | |
| 355 | + /** | |
| 356 | + * Return the escaped siteurl. | |
| 357 | + * | |
| 358 | + * @deprecated 1.23.1 | |
| 359 | + * | |
| 360 | + * @return string | |
| 361 | + */ | |
| 362 | + public static function site_url() { | |
| 363 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::site_url' ); | |
| 364 | + return Urls::site_url(); | |
| 365 | + } | |
| 366 | + | |
| 367 | + /** | |
| 368 | + * Return main site URL with a normalized protocol. | |
| 369 | + * | |
| 370 | + * @deprecated 1.23.1 | |
| 371 | + * | |
| 372 | + * @return string | |
| 373 | + */ | |
| 374 | + public static function main_network_site_url() { | |
| 375 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::main_network_site_url' ); | |
| 376 | + return Urls::main_network_site_url(); | |
| 377 | + } | |
| 378 | + | |
| 379 | + /** | |
| 380 | + * Return main site WordPress.com site ID. | |
| 381 | + * | |
| 382 | + * @return string | |
| 383 | + */ | |
| 384 | + public static function main_network_site_wpcom_id() { | |
| 385 | + /** | |
| 386 | + * Return the current site WPCOM ID for single site installs | |
| 387 | + */ | |
| 388 | + if ( ! is_multisite() ) { | |
| 389 | + return \Jetpack_Options::get_option( 'id' ); | |
| 390 | + } | |
| 391 | + | |
| 392 | + /** | |
| 393 | + * Return the main network site WPCOM ID for multi-site installs | |
| 394 | + */ | |
| 395 | + $current_network = get_network(); | |
| 396 | + switch_to_blog( (int) $current_network->blog_id ); | |
| 397 | + $wpcom_blog_id = \Jetpack_Options::get_option( 'id' ); | |
| 398 | + restore_current_blog(); | |
| 399 | + return $wpcom_blog_id; | |
| 400 | + } | |
| 401 | + | |
| 402 | + /** | |
| 403 | + * Return URL with a normalized protocol. | |
| 404 | + * | |
| 405 | + * @deprecated 1.23.1 | |
| 406 | + * | |
| 407 | + * @param string $callable Function name that was used to retrieve URL option. | |
| 408 | + * @param string $new_value URL Protocol to set URLs to. | |
| 409 | + * @return string Normalized URL. | |
| 410 | + */ | |
| 411 | + public static function get_protocol_normalized_url( $callable, $new_value ) { | |
| 412 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::get_protocol_normalized_url' ); | |
| 413 | + return Urls::get_protocol_normalized_url( $callable, $new_value ); | |
| 414 | + } | |
| 415 | + | |
| 416 | + /** | |
| 417 | + * Return URL from option or PHP constant. | |
| 418 | + * | |
| 419 | + * @deprecated 1.23.1 | |
| 420 | + * | |
| 421 | + * @param string $option_name (e.g. 'home'). | |
| 422 | + * | |
| 423 | + * @return mixed|null URL. | |
| 424 | + */ | |
| 425 | + public static function get_raw_url( $option_name ) { | |
| 426 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::get_raw_url' ); | |
| 427 | + return Urls::get_raw_url( $option_name ); | |
| 428 | + } | |
| 429 | + | |
| 430 | + /** | |
| 431 | + * Normalize domains by removing www unless declared in the site's option. | |
| 432 | + * | |
| 433 | + * @deprecated 1.23.1 | |
| 434 | + * | |
| 435 | + * @param string $option Option value from the site. | |
| 436 | + * @param callable $url_function Function retrieving the URL to normalize. | |
| 437 | + * @return mixed|string URL. | |
| 438 | + */ | |
| 439 | + public static function normalize_www_in_url( $option, $url_function ) { | |
| 440 | + _deprecated_function( __METHOD__, '1.23.1', '\\Automattic\\Jetpack\\Connection\\Urls::normalize_www_in_url' ); | |
| 441 | + return Urls::normalize_www_in_url( $option, $url_function ); | |
| 442 | + } | |
| 443 | + | |
| 444 | + /** | |
| 445 | + * Return filtered value of get_plugins. | |
| 446 | + * | |
| 447 | + * @return mixed|void | |
| 448 | + */ | |
| 449 | + public static function get_plugins() { | |
| 450 | + if ( ! function_exists( 'get_plugins' ) ) { | |
| 451 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; | |
| 452 | + } | |
| 453 | + | |
| 454 | + /** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */ | |
| 455 | + return apply_filters( 'all_plugins', get_plugins() ); | |
| 456 | + } | |
| 457 | + | |
| 458 | + /** | |
| 459 | + * Get custom action link tags that the plugin is using | |
| 460 | + * Ref: https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name) | |
| 461 | + * | |
| 462 | + * @param string $plugin_file_singular Particular plugin. | |
| 463 | + * @return array of plugin action links (key: link name value: url) | |
| 464 | + */ | |
| 465 | + public static function get_plugins_action_links( $plugin_file_singular = null ) { | |
| 466 | + // Some sites may have DOM disabled in PHP fail early. | |
| 467 | + if ( ! class_exists( 'DOMDocument' ) ) { | |
| 468 | + return array(); | |
| 469 | + } | |
| 470 | + $plugins_action_links = get_option( 'jetpack_plugin_api_action_links', array() ); | |
| 471 | + if ( ! empty( $plugins_action_links ) ) { | |
| 472 | + if ( $plugin_file_singular === null ) { | |
| 473 | + return $plugins_action_links; | |
| 474 | + } | |
| 475 | + return ( $plugins_action_links[ $plugin_file_singular ] ?? null ); | |
| 476 | + } | |
| 477 | + return array(); | |
| 478 | + } | |
| 479 | + | |
| 480 | + /** | |
| 481 | + * Return the WP version as defined in the $wp_version global. | |
| 482 | + * | |
| 483 | + * @return string | |
| 484 | + */ | |
| 485 | + public static function wp_version() { | |
| 486 | + global $wp_version; | |
| 487 | + return $wp_version; | |
| 488 | + } | |
| 489 | + | |
| 490 | + /** | |
| 491 | + * Return site icon url used on the site. | |
| 492 | + * | |
| 493 | + * @param int $size Size of requested icon in pixels. | |
| 494 | + * @return mixed|string|void | |
| 495 | + */ | |
| 496 | + public static function site_icon_url( $size = 512 ) { | |
| 497 | + $site_icon = get_site_icon_url( $size ); | |
| 498 | + return $site_icon ? $site_icon : get_option( 'jetpack_site_icon_url' ); | |
| 499 | + } | |
| 500 | + | |
| 501 | + /** | |
| 502 | + * Return roles registered on the site. | |
| 503 | + * | |
| 504 | + * @return array | |
| 505 | + */ | |
| 506 | + public static function roles() { | |
| 507 | + $wp_roles = wp_roles(); | |
| 508 | + return $wp_roles->roles; | |
| 509 | + } | |
| 510 | + | |
| 511 | + /** | |
| 512 | + * Determine time zone from WordPress' options "timezone_string" | |
| 513 | + * and "gmt_offset". | |
| 514 | + * | |
| 515 | + * 1. Check if `timezone_string` is set and return it. | |
| 516 | + * 2. Check if `gmt_offset` is set, formats UTC-offset from it and return it. | |
| 517 | + * 3. Default to "UTC+0" if nothing is set. | |
| 518 | + * | |
| 519 | + * Note: This function is specifically not using wp_timezone() to keep consistency with | |
| 520 | + * the existing formatting of the timezone string. | |
| 521 | + * | |
| 522 | + * @return string | |
| 523 | + */ | |
| 524 | + public static function get_timezone() { | |
| 525 | + $timezone_string = get_option( 'timezone_string' ); | |
| 526 | + | |
| 527 | + if ( ! empty( $timezone_string ) ) { | |
| 528 | + return str_replace( '_', ' ', $timezone_string ); | |
| 529 | + } | |
| 530 | + | |
| 531 | + $gmt_offset = get_option( 'gmt_offset', 0 ); | |
| 532 | + | |
| 533 | + $formatted_gmt_offset = sprintf( '%+g', (float) $gmt_offset ); | |
| 534 | + | |
| 535 | + $formatted_gmt_offset = str_replace( | |
| 536 | + array( '.25', '.5', '.75' ), | |
| 537 | + array( ':15', ':30', ':45' ), | |
| 538 | + $formatted_gmt_offset | |
| 539 | + ); | |
| 540 | + | |
| 541 | + /* translators: %s is UTC offset, e.g. "+1" */ | |
| 542 | + return sprintf( __( 'UTC%s', 'jetpack-sync' ), $formatted_gmt_offset ); | |
| 543 | + } | |
| 544 | + | |
| 545 | + /** | |
| 546 | + * Return list of paused themes. | |
| 547 | + * | |
| 548 | + * @return array|bool Array of paused themes or false if unsupported. | |
| 549 | + */ | |
| 550 | + public static function get_paused_themes() { | |
| 551 | + $paused_themes = wp_paused_themes(); | |
| 552 | + return $paused_themes->get_all(); | |
| 553 | + } | |
| 554 | + | |
| 555 | + /** | |
| 556 | + * Return list of paused plugins. | |
| 557 | + * | |
| 558 | + * @return array|bool Array of paused plugins or false if unsupported. | |
| 559 | + */ | |
| 560 | + public static function get_paused_plugins() { | |
| 561 | + $paused_plugins = wp_paused_plugins(); | |
| 562 | + return $paused_plugins->get_all(); | |
| 563 | + } | |
| 564 | + | |
| 565 | + /** | |
| 566 | + * Return the theme's supported features. | |
| 567 | + * Used for syncing the supported feature that we care about. | |
| 568 | + * | |
| 569 | + * @return array List of features that the theme supports. | |
| 570 | + */ | |
| 571 | + public static function get_theme_support() { | |
| 572 | + global $_wp_theme_features; | |
| 573 | + | |
| 574 | + $theme_support = array(); | |
| 575 | + foreach ( Defaults::$default_theme_support_whitelist as $theme_feature ) { | |
| 576 | + $has_support = current_theme_supports( $theme_feature ); | |
| 577 | + if ( $has_support ) { | |
| 578 | + $theme_support[ $theme_feature ] = $_wp_theme_features[ $theme_feature ]; | |
| 579 | + } | |
| 580 | + } | |
| 581 | + | |
| 582 | + return $theme_support; | |
| 583 | + } | |
| 584 | + | |
| 585 | + /** | |
| 586 | + * Returns if the current theme is a Full Site Editing theme. | |
| 587 | + * | |
| 588 | + * @since 1.49.0 Uses wp_is_block_theme() instead of deprecated gutenberg_is_fse_theme(). | |
| 589 | + * | |
| 590 | + * @return bool Theme is a Full Site Editing theme. | |
| 591 | + */ | |
| 592 | + public static function get_is_fse_theme() { | |
| 593 | + return wp_is_block_theme(); | |
| 594 | + } | |
| 595 | + | |
| 596 | + /** | |
| 597 | + * Returns the site's visibility as a `blog_public` value, or -1 when Jetpack considers the site private. | |
| 598 | + * | |
| 599 | + * Lets `jetpack_is_private_site` report the site as private to WordPress.com without changing | |
| 600 | + * the `blog_public` option itself, since core and other plugins do not expect a -1 there. | |
| 601 | + * | |
| 602 | + * @since 5.2.0 | |
| 603 | + * | |
| 604 | + * @return int -1 when private, otherwise the stored `blog_public` value. | |
| 605 | + */ | |
| 606 | + public static function get_site_visibility() { | |
| 607 | + if ( ( new Status() )->is_private_site() ) { | |
| 608 | + return -1; | |
| 609 | + } | |
| 610 | + | |
| 611 | + return (int) get_option( 'blog_public', 1 ); | |
| 612 | + } | |
| 613 | + | |
| 614 | + /** | |
| 615 | + * Wraps data in a way so that we can distinguish between objects and array and also prevent object recursion. | |
| 616 | + * | |
| 617 | + * @since 1.21.0 | |
| 618 | + * | |
| 619 | + * @param mixed $any Source data to be cleaned up. | |
| 620 | + * @param array $seen_nodes Built array of nodes. | |
| 621 | + * | |
| 622 | + * @return array | |
| 623 | + */ | |
| 624 | + public static function json_wrap( &$any, $seen_nodes = array() ) { | |
| 625 | + if ( is_object( $any ) ) { | |
| 626 | + $input = get_object_vars( $any ); | |
| 627 | + | |
| 628 | + // WordPress 6.9 introduced lazy-loading of WP_User `roles`, `caps`, and `allcaps` properties. | |
| 629 | + // It also made said properties protected, so we need to access them and set them as keys manually. | |
| 630 | + if ( $any instanceof \WP_User ) { | |
| 631 | + $roles = $any->roles; | |
| 632 | + $caps = $any->caps; | |
| 633 | + $allcaps = $any->allcaps; | |
| 634 | + $input['roles'] = $roles; | |
| 635 | + $input['caps'] = $caps; | |
| 636 | + $input['allcaps'] = $allcaps; | |
| 637 | + } | |
| 638 | + | |
| 639 | + $input['__o'] = 1; | |
| 640 | + } else { | |
| 641 | + $input = &$any; | |
| 642 | + } | |
| 643 | + | |
| 644 | + if ( is_array( $input ) ) { | |
| 645 | + $seen_nodes[] = &$any; | |
| 646 | + | |
| 647 | + $return = array(); | |
| 648 | + | |
| 649 | + foreach ( $input as $k => &$v ) { | |
| 650 | + if ( ( is_array( $v ) || is_object( $v ) ) ) { | |
| 651 | + if ( in_array( $v, $seen_nodes, true ) ) { | |
| 652 | + continue; | |
| 653 | + } | |
| 654 | + $return[ $k ] = self::json_wrap( $v, $seen_nodes ); | |
| 655 | + } else { | |
| 656 | + $return[ $k ] = $v; | |
| 657 | + } | |
| 658 | + } | |
| 659 | + | |
| 660 | + return $return; | |
| 661 | + } | |
| 662 | + | |
| 663 | + return $any; | |
| 664 | + } | |
| 665 | + | |
| 666 | + /** | |
| 667 | + * Return the list of installed themes | |
| 668 | + * | |
| 669 | + * @since 1.31.0 | |
| 670 | + * | |
| 671 | + * @return array | |
| 672 | + */ | |
| 673 | + public static function get_themes() { | |
| 674 | + $current_stylesheet = get_stylesheet(); | |
| 675 | + $installed_themes = wp_get_themes(); | |
| 676 | + $synced_headers = array( 'Name', 'ThemeURI', 'Author', 'Version', 'Template', 'Status', 'TextDomain', 'RequiresWP', 'RequiresPHP' ); | |
| 677 | + $themes = array(); | |
| 678 | + foreach ( $installed_themes as $stylesheet => $theme ) { | |
| 679 | + $themes[ $stylesheet ] = array(); | |
| 680 | + foreach ( $synced_headers as $header ) { | |
| 681 | + $themes[ $stylesheet ][ $header ] = $theme->get( $header ); | |
| 682 | + } | |
| 683 | + $themes[ $stylesheet ]['active'] = $stylesheet === $current_stylesheet; | |
| 684 | + if ( method_exists( $theme, 'is_block_theme' ) ) { | |
| 685 | + $themes[ $stylesheet ]['is_block_theme'] = $theme->is_block_theme(); | |
| 686 | + } | |
| 687 | + } | |
| 688 | + /** | |
| 689 | + * Filters the output of Sync's get_theme callable | |
| 690 | + * | |
| 691 | + * @since 1.31.0 | |
| 692 | + * | |
| 693 | + * @param array $themes The list of installed themes formatted in an array with a collection of information extracted from the Theme's headers | |
| 694 | + */ | |
| 695 | + return apply_filters( 'jetpack_sync_get_themes_callable', $themes ); | |
| 696 | + } | |
| 697 | + | |
| 698 | + /** | |
| 699 | + * Return the list of active Jetpack modules. | |
| 700 | + * | |
| 701 | + * @since 1.34.0 | |
| 702 | + * | |
| 703 | + * @return array | |
| 704 | + */ | |
| 705 | + public static function get_active_modules() { | |
| 706 | + return ( new Jetpack_Modules() )->get_active(); | |
| 707 | + } | |
| 708 | + | |
| 709 | + /** | |
| 710 | + * Return a list of PHP modules that we want to track. | |
| 711 | + * | |
| 712 | + * @since 1.50.0 | |
| 713 | + * | |
| 714 | + * @return array | |
| 715 | + */ | |
| 716 | + public static function get_loaded_extensions() { | |
| 717 | + if ( function_exists( 'get_loaded_extensions' ) ) { | |
| 718 | + return get_loaded_extensions(); | |
| 719 | + } | |
| 720 | + | |
| 721 | + // If a hosting provider has blocked get_loaded_extensions for any reason, | |
| 722 | + // we check extensions manually. | |
| 723 | + | |
| 724 | + $extensions_to_check = array( | |
| 725 | + 'libxml' => array( 'class' => 'libXMLError' ), | |
| 726 | + 'xml' => array( 'function' => 'xml_parse' ), | |
| 727 | + 'dom' => array( 'class' => 'DOMDocument' ), | |
| 728 | + 'xdebug' => array( 'function' => 'xdebug_break' ), | |
| 729 | + ); | |
| 730 | + | |
| 731 | + $enabled_extensions = array(); | |
| 732 | + foreach ( $extensions_to_check as $extension_name => $extension ) { | |
| 733 | + if ( | |
| 734 | + ( isset( $extension['function'] ) | |
| 735 | + && function_exists( $extension['function'] ) ) | |
| 736 | + || class_exists( $extension['class'] ) | |
| 737 | + ) { | |
| 738 | + $enabled_extensions[] = $extension_name; | |
| 739 | + } | |
| 740 | + } | |
| 741 | + | |
| 742 | + return $enabled_extensions; | |
| 743 | + } | |
| 744 | + | |
| 745 | + /** | |
| 746 | + * Return the list of active connected Jetpack plugins. | |
| 747 | + * | |
| 748 | + * @since 3.2.0 | |
| 749 | + * | |
| 750 | + * @return array | |
| 751 | + */ | |
| 752 | + public static function get_jetpack_connection_active_plugins() { | |
| 753 | + return ( new Manager() )->get_connected_plugins(); | |
| 754 | + } | |
| 755 | + | |
| 756 | + /** | |
| 757 | + * Return the list of active sync modules. | |
| 758 | + * | |
| 759 | + * @since 3.6.0 | |
| 760 | + * | |
| 761 | + * @return array | |
| 762 | + */ | |
| 763 | + public static function get_jetpack_sync_active_modules() { | |
| 764 | + | |
| 765 | + /** This filter is documented in projects/packages/sync/src/class-modules.php */ | |
| 766 | + $modules = apply_filters( 'jetpack_sync_modules', Modules::DEFAULT_SYNC_MODULES ); | |
| 767 | + $modules = array_unique( $modules ); | |
| 768 | + $modules = array_map( 'wp_normalize_path', $modules ); | |
| 769 | + return $modules; | |
| 770 | + } | |
| 771 | + | |
| 772 | + /** | |
| 773 | + * Return the list of Jetpack package versions. | |
| 774 | + * | |
| 775 | + * @since 4.11.1 | |
| 776 | + * | |
| 777 | + * @return array | |
| 778 | + */ | |
| 779 | + public static function get_jetpack_package_versions() { | |
| 780 | + return apply_filters( 'jetpack_package_versions', array() ); | |
| 781 | + } | |
| 782 | +} | |