diff options
Diffstat (limited to 'plugins/jetpack/class.jetpack.php')
-rw-r--r-- | plugins/jetpack/class.jetpack.php | 1088 |
1 files changed, 304 insertions, 784 deletions
diff --git a/plugins/jetpack/class.jetpack.php b/plugins/jetpack/class.jetpack.php index acd8c33e..f995fc45 100644 --- a/plugins/jetpack/class.jetpack.php +++ b/plugins/jetpack/class.jetpack.php @@ -17,17 +17,22 @@ use Automattic\Jetpack\Connection\Rest_Authentication as Connection_Rest_Authent use Automattic\Jetpack\Connection\Secrets; use Automattic\Jetpack\Connection\Tokens; use Automattic\Jetpack\Connection\Utils as Connection_Utils; -use Automattic\Jetpack\Connection\Webhooks as Connection_Webhooks; use Automattic\Jetpack\Constants; +use Automattic\Jetpack\CookieState; use Automattic\Jetpack\Device_Detection\User_Agent_Info; +use Automattic\Jetpack\Errors; +use Automattic\Jetpack\Files; use Automattic\Jetpack\Identity_Crisis; use Automattic\Jetpack\Licensing; +use Automattic\Jetpack\Modules; use Automattic\Jetpack\My_Jetpack\Initializer as My_Jetpack_Initializer; use Automattic\Jetpack\Partner; +use Automattic\Jetpack\Paths; use Automattic\Jetpack\Plugin\Tracking as Plugin_Tracking; use Automattic\Jetpack\Redirect; use Automattic\Jetpack\Status; use Automattic\Jetpack\Status\Host; +use Automattic\Jetpack\Status\Visitor; use Automattic\Jetpack\Sync\Actions as Sync_Actions; use Automattic\Jetpack\Sync\Health; use Automattic\Jetpack\Sync\Sender; @@ -72,7 +77,7 @@ class Jetpack { /** * The handles of styles that are concatenated into jetpack.css. * - * When making changes to that list, you must also update concat_list in tools/builder/frontend-css.js. + * When making changes to that list, you must also update concat_list in tools/webpack.config.css.js. * * @var array The handles of styles that are concatenated into jetpack.css. */ @@ -114,7 +119,7 @@ class Jetpack { * * @var array */ - static $min_assets = array(); + public static $min_assets = array(); /** * Plugins to deactivate. @@ -436,7 +441,7 @@ class Jetpack { * @since 2.3.3 * @var Jetpack */ - static $instance = false; + public static $instance = false; /** * Singleton @@ -456,10 +461,10 @@ class Jetpack { /** * Must never be called statically */ - function plugin_upgrade() { + public function plugin_upgrade() { if ( self::is_connection_ready() ) { list( $version ) = explode( ':', Jetpack_Options::get_option( 'version' ) ); - if ( JETPACK__VERSION != $version ) { + if ( JETPACK__VERSION !== $version ) { // Prevent multiple upgrades at once - only a single process should trigger // an upgrade to avoid stampedes. if ( false !== get_transient( self::$plugin_upgrade_lock_key ) ) { @@ -548,7 +553,7 @@ class Jetpack { /** * Runs upgrade routines that need to have modules loaded. */ - static function upgrade_on_load() { + public static function upgrade_on_load() { // Not attempting any upgrades if jetpack_modules_loaded did not fire. // This can happen in case Jetpack has been just upgraded and is @@ -587,58 +592,8 @@ class Jetpack { * * @return $success bool true for success, false for failure. */ - static function update_active_modules( $modules ) { - $current_modules = Jetpack_Options::get_option( 'active_modules', array() ); - $active_modules = self::get_active_modules(); - $new_active_modules = array_diff( $modules, $current_modules ); - $new_inactive_modules = array_diff( $active_modules, $modules ); - $new_current_modules = array_diff( array_merge( $current_modules, $new_active_modules ), $new_inactive_modules ); - $reindexed_modules = array_values( $new_current_modules ); - $success = Jetpack_Options::update_option( 'active_modules', array_unique( $reindexed_modules ) ); - - foreach ( $new_active_modules as $module ) { - /** - * Fires when a specific module is activated. - * - * @since 1.9.0 - * - * @param string $module Module slug. - * @param boolean $success whether the module was activated. @since 4.2 - */ - do_action( 'jetpack_activate_module', $module, $success ); - /** - * Fires when a module is activated. - * The dynamic part of the filter, $module, is the module slug. - * - * @since 1.9.0 - * - * @param string $module Module slug. - */ - do_action( "jetpack_activate_module_$module", $module ); - } - - foreach ( $new_inactive_modules as $module ) { - /** - * Fired after a module has been deactivated. - * - * @since 4.2.0 - * - * @param string $module Module slug. - * @param boolean $success whether the module was deactivated. - */ - do_action( 'jetpack_deactivate_module', $module, $success ); - /** - * Fires when a module is deactivated. - * The dynamic part of the filter, $module, is the module slug. - * - * @since 1.9.0 - * - * @param string $module Module slug. - */ - do_action( "jetpack_deactivate_module_$module", $module ); - } - - return $success; + public static function update_active_modules( $modules ) { + return ( new Modules() )->update_active( $modules ); } /** @@ -646,7 +601,7 @@ class Jetpack { * * @return void */ - static function delete_active_modules() { + public static function delete_active_modules() { self::update_active_modules( array() ); } @@ -853,6 +808,9 @@ class Jetpack { // Register product descriptions for partner coupon usage. add_filter( 'jetpack_partner_coupon_products', array( $this, 'get_partner_coupon_product_descriptions' ) ); + + // Actions for conditional recommendations. + add_action( 'plugins_loaded', array( 'Jetpack_Recommendations', 'init_conditional_recommendation_actions' ) ); } /** @@ -864,14 +822,20 @@ class Jetpack { foreach ( array( - 'sync', 'jitm', + 'sync', + 'waf', ) as $feature ) { $config->ensure( $feature ); } + $modules = new Automattic\Jetpack\Modules(); + if ( $modules->is_active( 'publicize' ) ) { + $config->ensure( 'publicize' ); + } + $config->ensure( 'connection', array( @@ -889,6 +853,12 @@ class Jetpack { ) ); + $config->ensure( 'search' ); + + if ( defined( 'ENABLE_WORDADS_SHARED_UI' ) && ENABLE_WORDADS_SHARED_UI ) { + $config->ensure( 'wordads' ); + } + if ( ! $this->connection_manager ) { $this->connection_manager = new Connection_Manager( 'jetpack' ); } @@ -960,7 +930,7 @@ class Jetpack { */ do_action( 'jetpack_loaded', $this ); - add_filter( 'map_meta_cap', array( $this, 'jetpack_custom_caps' ), 1, 4 ); + add_filter( 'map_meta_cap', array( $this, 'jetpack_custom_caps' ), 1, 2 ); } /** @@ -978,7 +948,7 @@ class Jetpack { * * @return array */ - function allow_wpcom_domain( $domains ) { + public function allow_wpcom_domain( $domains ) { if ( empty( $domains ) ) { $domains = array(); } @@ -994,7 +964,7 @@ class Jetpack { * * @return string */ - function point_edit_post_links_to_calypso( $default_url, $post_id ) { + public function point_edit_post_links_to_calypso( $default_url, $post_id ) { $post = get_post( $post_id ); if ( empty( $post ) ) { @@ -1031,7 +1001,7 @@ class Jetpack { * * @return string */ - function point_edit_comment_links_to_calypso( $url ) { + public function point_edit_comment_links_to_calypso( $url ) { // Take the `query` key value from the URL, and parse its parts to the $query_args. `amp;c` matches the comment ID. wp_parse_str( wp_parse_url( $url, PHP_URL_QUERY ), $query_args ); @@ -1057,7 +1027,6 @@ class Jetpack { $jetpack_callables = array( 'single_user_site' => array( 'Jetpack', 'is_single_user_site' ), 'updates' => array( 'Jetpack', 'get_updates' ), - 'active_modules' => array( 'Jetpack', 'get_active_modules' ), 'available_jetpack_blocks' => array( 'Jetpack_Gutenberg', 'get_availability' ), // Includes both Gutenberg blocks *and* plugins. ); $callables = array_merge( $callables, $jetpack_callables ); @@ -1108,12 +1077,17 @@ class Jetpack { * * @deprecated since 9.8. */ - function jetpack_track_last_sync_callback( $params ) { + public function jetpack_track_last_sync_callback( $params ) { _deprecated_function( __METHOD__, 'jetpack-9.8', '\Automattic\Jetpack\JITMS\JITM->jetpack_track_last_sync_callback' ); return Automattic\Jetpack\JITMS\JITM::get_instance()->jetpack_track_last_sync_callback( $params ); } - function jetpack_connection_banner_callback() { + /** + * Jetpack Connection banner callback function. + * + * @return void + */ + public function jetpack_connection_banner_callback() { check_ajax_referer( 'jp-connection-banner-nonce', 'nonce' ); // Disable the banner dismiss functionality if the pre-connection prompt helpers filter is set. @@ -1131,7 +1105,7 @@ class Jetpack { /** * If there are any stats that need to be pushed, but haven't been, push them now. */ - function push_stats() { + public function push_stats() { if ( ! empty( $this->stats ) ) { $this->do_stats( 'server_side' ); } @@ -1142,10 +1116,8 @@ class Jetpack { * * @param string[] $caps Array of the user's capabilities. * @param string $cap Capability name. - * @param int $user_id The user ID. - * @param array $args Adds the context to the cap. Typically the object ID. */ - public function jetpack_custom_caps( $caps, $cap, $user_id, $args ) { + public function jetpack_custom_caps( $caps, $cap ) { switch ( $cap ) { case 'jetpack_manage_modules': case 'jetpack_activate_modules': @@ -1194,7 +1166,8 @@ class Jetpack { 'jetpack-gallery-settings', Assets::get_file_url_for_environment( '_inc/build/gallery-settings.min.js', '_inc/gallery-settings.js' ), array( 'media-views' ), - '20121225' + '20121225', + true ); } @@ -1213,7 +1186,7 @@ class Jetpack { 'jetpack-facebook-embed', Assets::get_file_url_for_environment( '_inc/build/facebook-embed.min.js', '_inc/facebook-embed.js' ), array(), - null, + JETPACK__VERSION, true ); @@ -1257,7 +1230,7 @@ class Jetpack { * @param string $lang Language code. * @return string|bool */ - function guess_locale_from_lang( $lang ) { + public function guess_locale_from_lang( $lang ) { if ( 'en' === $lang || 'en_US' === $lang || ! $lang ) { return 'en_US'; } @@ -1302,7 +1275,7 @@ class Jetpack { * * @return string|bool */ - function get_locale() { + public function get_locale() { $locale = $this->guess_locale_from_lang( get_locale() ); if ( ! $locale ) { @@ -1333,7 +1306,7 @@ class Jetpack { * @return string */ public static function network_allow_new_registrations() { - return ( in_array( get_site_option( 'registration' ), array( 'none', 'user', 'blog', 'all' ) ) ? get_site_option( 'registration' ) : 'none' ); + return ( in_array( get_site_option( 'registration' ), array( 'none', 'user', 'blog', 'all' ), true ) ? get_site_option( 'registration' ) : 'none' ); } /** * Does the network allow admins to add new users. @@ -1393,10 +1366,10 @@ class Jetpack { * @param string $role The new role. * @param array $old_roles An array of the user's previous roles. */ - function maybe_clear_other_linked_admins_transient( $user_id, $role, $old_roles = null ) { - if ( 'administrator' == $role - || ( is_array( $old_roles ) && in_array( 'administrator', $old_roles ) ) - || is_null( $old_roles ) + public function maybe_clear_other_linked_admins_transient( $user_id, $role, $old_roles = null ) { + if ( 'administrator' === $role + || ( is_array( $old_roles ) && in_array( 'administrator', $old_roles, true ) ) + || $old_roles === null ) { delete_transient( 'jetpack_other_linked_admins' ); } @@ -1410,7 +1383,7 @@ class Jetpack { * * @return mixed False if no other users are linked, Int if there are. */ - static function get_other_linked_admins() { + public static function get_other_linked_admins() { $other_linked_users = get_transient( 'jetpack_other_linked_admins' ); if ( false === $other_linked_users ) { @@ -1493,7 +1466,8 @@ class Jetpack { public static function is_single_user_site() { global $wpdb; - if ( false === ( $some_users = get_transient( 'jetpack_is_single_user' ) ) ) { + $some_users = get_transient( 'jetpack_is_single_user' ); + if ( false === $some_users ) { $some_users = $wpdb->get_var( "SELECT COUNT(*) FROM (SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}capabilities' LIMIT 2) AS someusers" ); set_transient( 'jetpack_is_single_user', (int) $some_users, 12 * HOUR_IN_SECONDS ); } @@ -1513,7 +1487,7 @@ class Jetpack { require_once ABSPATH . 'wp-admin/includes/template.php'; $filesystem_method = get_filesystem_method(); - if ( $filesystem_method === 'direct' ) { + if ( 'direct' === $filesystem_method ) { return 1; } @@ -1647,6 +1621,7 @@ class Jetpack { * A site is considered as being onboarded if it currently has an onboarding token. * * @since 5.8 + * @deprecated Use \Automattic\Jetpack\Status()->is_onboarding() * * @access public * @static @@ -1654,7 +1629,12 @@ class Jetpack { * @return bool True if the site is currently onboarding, false otherwise */ public static function is_onboarding() { - return Jetpack_Options::get_option( 'onboarding' ) !== false; + _deprecated_function( __METHOD__, 'jetpack-10.9', 'Automattic\\Jetpack\\Status\\is_onboarding' ); + + if ( ! method_exists( 'Automattic\Jetpack\Status', 'is_onboarding' ) ) { + return Jetpack_Options::get_option( 'onboarding' ) !== false; + } + return ( new Status() )->is_onboarding(); } /** @@ -1698,7 +1678,7 @@ class Jetpack { $notice .= ' ' . self::development_mode_trigger_text(); - echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; + echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All provided text. } // Throw up a notice if using a development version and as for feedback. @@ -1706,14 +1686,14 @@ class Jetpack { /* translators: %s is a URL */ $notice = sprintf( __( 'You are currently running a development version of Jetpack. <a href="%s" target="_blank">Submit your feedback</a>', 'jetpack' ), Redirect::get_url( 'jetpack-contact-support-beta-group' ) ); - echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; + echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All provided text. } // Throw up a notice if using staging mode. if ( ( new Status() )->is_staging_site() ) { /* translators: %s is a URL */ $notice = sprintf( __( 'You are running Jetpack on a <a href="%s" target="_blank">staging server</a>.', 'jetpack' ), Redirect::get_url( 'jetpack-support-staging-sites' ) ); - echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; + echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All provided text. } } @@ -1794,38 +1774,32 @@ class Jetpack { * * @param bool $check_all_headers Check all headers? Default is `false`. * + * @deprecated Jetpack 10.6 + * * @return string Current user IP address. */ public static function current_user_ip( $check_all_headers = false ) { - if ( $check_all_headers ) { - foreach ( array( - 'HTTP_CF_CONNECTING_IP', - 'HTTP_CLIENT_IP', - 'HTTP_X_FORWARDED_FOR', - 'HTTP_X_FORWARDED', - 'HTTP_X_CLUSTER_CLIENT_IP', - 'HTTP_FORWARDED_FOR', - 'HTTP_FORWARDED', - 'HTTP_VIA', - ) as $key ) { - if ( ! empty( $_SERVER[ $key ] ) ) { - return $_SERVER[ $key ]; - } - } - } + _deprecated_function( __METHOD__, 'jetpack-10.6', 'Automattic\\Jetpack\\Status\\Visitor::get_ip' ); - return ! empty( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : ''; + return ( new Visitor() )->get_ip( $check_all_headers ); } /** * Loads the currently active modules. */ public static function load_modules() { - $is_offline_mode = ( new Status() )->is_offline_mode(); + $status = new Status(); + + if ( method_exists( $status, 'is_onboarding' ) ) { + $is_onboarding = $status->is_onboarding(); + } else { + $is_onboarding = self::is_onboarding(); + } + if ( ! self::is_connection_ready() - && ! $is_offline_mode - && ! self::is_onboarding() + && ! $status->is_offline_mode() + && ! $is_onboarding && ( ! is_multisite() || ! get_site_option( 'jetpack_protect_active' ) @@ -1836,7 +1810,8 @@ class Jetpack { $version = Jetpack_Options::get_option( 'version' ); if ( ! $version ) { - $version = $old_version = JETPACK__VERSION . ':' . time(); + $version = JETPACK__VERSION . ':' . time(); + $old_version = $version; /** This action is documented in class.jetpack.php */ do_action( 'updating_jetpack_version', $version, false ); Jetpack_Options::update_options( compact( 'version', 'old_version' ) ); @@ -1874,13 +1849,13 @@ class Jetpack { foreach ( $modules as $index => $module ) { // If we're in offline/site-connection mode, disable modules requiring a connection/user connection. - if ( $is_offline_mode || $is_site_connection ) { + if ( $status->is_offline_mode() || $is_site_connection ) { // Prime the pump if we need to. if ( empty( $modules_data[ $module ] ) ) { $modules_data[ $module ] = self::get_module( $module ); } // If the module requires a connection, but we're in local mode, don't include it. - if ( $is_offline_mode && $modules_data[ $module ]['requires_connection'] ) { + if ( $status->is_offline_mode() && $modules_data[ $module ]['requires_connection'] ) { continue; } @@ -1893,7 +1868,7 @@ class Jetpack { continue; } - if ( ! include_once self::get_module_path( $module ) ) { + if ( ! include_once self::get_module_path( $module ) ) { // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.NotAbsolutePath unset( $modules[ $index ] ); self::update_active_modules( array_values( $modules ) ); continue; @@ -1981,7 +1956,7 @@ class Jetpack { $plugins = array(); foreach ( $all_plugins as $path => $plugin_data ) { $plugins[ $path ] = array( - 'is_active' => in_array( $path, $active_plugins ), + 'is_active' => in_array( $path, $active_plugins, true ), 'file' => $path, 'name' => $plugin_data['Name'], 'version' => $plugin_data['Version'], @@ -2011,7 +1986,7 @@ class Jetpack { } $themes[ $slug ] = array( - 'is_active_theme' => $slug == wp_get_theme()->get_template(), + 'is_active_theme' => wp_get_theme()->get_template() === $slug, 'slug' => $slug, 'theme_root' => $theme_data->get_theme_root_uri(), 'parent' => $theme_data->parent(), @@ -2031,7 +2006,7 @@ class Jetpack { * @param string $plugin Plugin to check in 'folder/file.php` format. */ public static function is_plugin_active( $plugin = 'jetpack/jetpack.php' ) { - return in_array( $plugin, self::get_active_plugins() ); + return in_array( $plugin, self::get_active_plugins(), true ); } /** @@ -2043,7 +2018,8 @@ class Jetpack { * @return void */ public function check_open_graph() { - if ( in_array( 'publicize', self::get_active_modules() ) || in_array( 'sharedaddy', self::get_active_modules() ) ) { + if ( in_array( 'publicize', self::get_active_modules(), true ) || in_array( 'sharedaddy', self::get_active_modules(), true ) ) { + include_once JETPACK__PLUGIN_DIR . 'enhanced-open-graph.php'; add_filter( 'jetpack_enable_open_graph', '__return_true', 0 ); } @@ -2051,7 +2027,7 @@ class Jetpack { if ( ! empty( $active_plugins ) ) { foreach ( $this->open_graph_conflicting_plugins as $plugin ) { - if ( in_array( $plugin, $active_plugins ) ) { + if ( in_array( $plugin, $active_plugins, true ) ) { add_filter( 'jetpack_enable_open_graph', '__return_false', 99 ); break; } @@ -2084,7 +2060,7 @@ class Jetpack { if ( ! empty( $active_plugins ) ) { foreach ( $this->twitter_cards_conflicting_plugins as $plugin ) { - if ( in_array( $plugin, $active_plugins ) ) { + if ( in_array( $plugin, $active_plugins, true ) ) { add_filter( 'jetpack_disable_twitter_cards', '__return_true', 99 ); break; } @@ -2136,33 +2112,7 @@ class Jetpack { * @return array Array of absolute paths to the PHP files. */ public static function glob_php( $absolute_path ) { - if ( function_exists( 'glob' ) ) { - return glob( "$absolute_path/*.php" ); - } - - $absolute_path = untrailingslashit( $absolute_path ); - $files = array(); - if ( ! $dir = @opendir( $absolute_path ) ) { - return $files; - } - - while ( false !== $file = readdir( $dir ) ) { - if ( '.' == substr( $file, 0, 1 ) || '.php' != substr( $file, -4 ) ) { - continue; - } - - $file = "$absolute_path/$file"; - - if ( ! is_file( $file ) ) { - continue; - } - - $files[] = $file; - } - - closedir( $dir ); - - return $files; + return ( new Files() )->glob_php( $absolute_path ); } /** @@ -2179,7 +2129,9 @@ class Jetpack { $jetpack_old_version = Jetpack_Options::get_option( 'version' ); if ( ! $jetpack_old_version ) { - $jetpack_old_version = $version = $old_version = '1.1:' . time(); + $old_version = '1.1:' . time(); + $version = $old_version; + $jetpack_old_version = $version; /** This action is documented in class.jetpack.php */ do_action( 'updating_jetpack_version', $version, false ); Jetpack_Options::update_options( compact( 'version', 'old_version' ) ); @@ -2244,79 +2196,7 @@ class Jetpack { * @return array $modules Array of module slugs */ public static function get_available_modules( $min_version = false, $max_version = false, $requires_connection = null, $requires_user_connection = null ) { - static $modules = null; - - if ( ! isset( $modules ) ) { - $available_modules_option = Jetpack_Options::get_option( 'available_modules', array() ); - // Use the cache if we're on the front-end and it's available... - if ( ! is_admin() && ! empty( $available_modules_option[ JETPACK__VERSION ] ) ) { - $modules = $available_modules_option[ JETPACK__VERSION ]; - } else { - $files = self::glob_php( JETPACK__PLUGIN_DIR . 'modules' ); - - $modules = array(); - - foreach ( $files as $file ) { - $slug = self::get_module_slug( $file ); - $headers = self::get_module( $slug ); - - if ( ! $headers ) { - continue; - } - - $modules[ $slug ] = $headers['introduced']; - } - - Jetpack_Options::update_option( - 'available_modules', - array( - JETPACK__VERSION => $modules, - ) - ); - } - } - - /** - * Filters the array of modules available to be activated. - * - * @since 2.4.0 - * - * @param array $modules Array of available modules. - * @param string $min_version Minimum version number required to use modules. - * @param string $max_version Maximum version number required to use modules. - * @param bool|null $requires_connection Value of the Requires Connection filter. - * @param bool|null $requires_user_connection Value of the Requires User Connection filter. - */ - $mods = apply_filters( 'jetpack_get_available_modules', $modules, $min_version, $max_version, $requires_connection, $requires_user_connection ); - - if ( ! $min_version && ! $max_version && is_null( $requires_connection ) && is_null( $requires_user_connection ) ) { - return array_keys( $mods ); - } - - $r = array(); - foreach ( $mods as $slug => $introduced ) { - if ( $min_version && version_compare( $min_version, $introduced, '>=' ) ) { - continue; - } - - if ( $max_version && version_compare( $max_version, $introduced, '<' ) ) { - continue; - } - - $mod_details = self::get_module( $slug ); - - if ( null !== $requires_connection && (bool) $requires_connection !== $mod_details['requires_connection'] ) { - continue; - } - - if ( null !== $requires_user_connection && (bool) $requires_user_connection !== $mod_details['requires_user_connection'] ) { - continue; - } - - $r[] = $slug; - } - - return $r; + return ( new Modules() )->get_available( $min_version, $max_version, $requires_connection, $requires_user_connection ); } /** @@ -2380,7 +2260,7 @@ class Jetpack { * @param array $modules Array of Jetpack modules. * @return array */ - function handle_deprecated_modules( $modules ) { + public function handle_deprecated_modules( $modules ) { $deprecated_modules = array( 'debug' => null, // Closed out and moved to the debugger library. 'wpcc' => 'sso', // Closed out in 2.6 -- SSO provides the same functionality. @@ -2419,7 +2299,7 @@ class Jetpack { * @param array $modules Array of Jetpack modules. * @return array */ - function filter_default_modules( $modules ) { + public function filter_default_modules( $modules ) { $active_plugins = self::get_active_plugins(); @@ -2430,9 +2310,9 @@ class Jetpack { // If there are potential conflicts for it... if ( ! empty( $this->conflicting_plugins[ $module ] ) ) { // For each potential conflict... - foreach ( $this->conflicting_plugins[ $module ] as $title => $plugin ) { + foreach ( $this->conflicting_plugins[ $module ] as $plugin ) { // If that conflicting plugin is active... - if ( in_array( $plugin, $active_plugins ) ) { + if ( in_array( $plugin, $active_plugins, true ) ) { // Remove that item from being auto-activated. unset( $modules[ $key ] ); } @@ -2452,7 +2332,7 @@ class Jetpack { * @return string Module slug. */ public static function get_module_slug( $file ) { - return str_replace( '.php', '', basename( $file ) ); + return ( new Modules() )->get_slug( $file ); } /** @@ -2461,15 +2341,7 @@ class Jetpack { * @param string $slug Module slug. */ public static function get_module_path( $slug ) { - /** - * Filters the path of a modules. - * - * @since 7.4.0 - * - * @param array $return The absolute path to a module's root php file - * @param string $slug The module slug - */ - return apply_filters( 'jetpack_get_module_path', JETPACK__PLUGIN_DIR . "modules/$slug.php", $slug ); + return ( new Modules() )->get_path( $slug ); } /** @@ -2480,97 +2352,7 @@ class Jetpack { * @param string $module The module slug. */ public static function get_module( $module ) { - static $modules_details; - - if ( jetpack_has_no_module_info( $module ) ) { - return false; - } - - $file = self::get_module_path( self::get_module_slug( $module ) ); - - if ( isset( $modules_details[ $module ] ) ) { - $mod = $modules_details[ $module ]; - } else { - $mod = jetpack_get_module_info( $module ); - - if ( null === $mod ) { - // Try to get the module info from the file as a fallback. - $mod = self::get_file_data( $file, jetpack_get_all_module_header_names() ); - - if ( empty( $mod['name'] ) ) { - // No info for this module. - return false; - } - } - - $mod['sort'] = empty( $mod['sort'] ) ? 10 : (int) $mod['sort']; - $mod['recommendation_order'] = empty( $mod['recommendation_order'] ) ? 20 : (int) $mod['recommendation_order']; - $mod['deactivate'] = empty( $mod['deactivate'] ); - $mod['free'] = empty( $mod['free'] ); - $mod['requires_connection'] = ( ! empty( $mod['requires_connection'] ) && 'No' === $mod['requires_connection'] ) ? false : true; - $mod['requires_user_connection'] = ( empty( $mod['requires_user_connection'] ) || 'No' === $mod['requires_user_connection'] ) ? false : true; - - if ( empty( $mod['auto_activate'] ) || ! in_array( strtolower( $mod['auto_activate'] ), array( 'yes', 'no', 'public' ), true ) ) { - $mod['auto_activate'] = 'No'; - } else { - $mod['auto_activate'] = (string) $mod['auto_activate']; - } - - if ( $mod['module_tags'] ) { - $mod['module_tags'] = explode( ',', $mod['module_tags'] ); - $mod['module_tags'] = array_map( 'trim', $mod['module_tags'] ); - $mod['module_tags'] = array_map( array( __CLASS__, 'translate_module_tag' ), $mod['module_tags'] ); - } else { - $mod['module_tags'] = array( self::translate_module_tag( 'Other' ) ); - } - - if ( $mod['plan_classes'] ) { - $mod['plan_classes'] = explode( ',', $mod['plan_classes'] ); - $mod['plan_classes'] = array_map( 'strtolower', array_map( 'trim', $mod['plan_classes'] ) ); - } else { - $mod['plan_classes'] = array( 'free' ); - } - - if ( $mod['feature'] ) { - $mod['feature'] = explode( ',', $mod['feature'] ); - $mod['feature'] = array_map( 'trim', $mod['feature'] ); - } else { - $mod['feature'] = array( self::translate_module_tag( 'Other' ) ); - } - - $modules_details[ $module ] = $mod; - - } - - /** - * Filters the feature array on a module. - * - * This filter allows you to control where each module is filtered: Recommended, - * and the default "Other" listing. - * - * @since 3.5.0 - * - * @param array $mod['feature'] The areas to feature this module: - * 'Recommended' shows on the main Jetpack admin screen. - * 'Other' should be the default if no other value is in the array. - * @param string $module The slug of the module, e.g. sharedaddy. - * @param array $mod All the currently assembled module data. - */ - $mod['feature'] = apply_filters( 'jetpack_module_feature', $mod['feature'], $module, $mod ); - - /** - * Filter the returned data about a module. - * - * This filter allows overriding any info about Jetpack modules. It is dangerous, - * so please be careful. - * - * @since 3.6.0 - * - * @param array $mod The details of the requested module. - * @param string $module The slug of the module, e.g. sharedaddy - * @param string $file The path to the module source file. - */ - return apply_filters( 'jetpack_get_module', $mod, $module, $file ); + return ( new Modules() )->get( $module ); } /** @@ -2580,37 +2362,7 @@ class Jetpack { * @param array $headers List of headers, in the format array( 'HeaderKey' => 'Header Name' ). */ public static function get_file_data( $file, $headers ) { - // Get just the filename from $file (i.e. exclude full path) so that a consistent hash is generated. - $file_name = basename( $file ); - - $cache_key = 'jetpack_file_data_' . JETPACK__VERSION; - - $file_data_option = get_transient( $cache_key ); - - if ( ! is_array( $file_data_option ) ) { - delete_transient( $cache_key ); - $file_data_option = false; - } - - if ( false === $file_data_option ) { - $file_data_option = array(); - } - - $key = md5( $file_name . serialize( $headers ) ); - $refresh_cache = is_admin() && isset( $_GET['page'] ) && 'jetpack' === substr( $_GET['page'], 0, 7 ); - - // If we don't need to refresh the cache, and already have the value, short-circuit! - if ( ! $refresh_cache && isset( $file_data_option[ $key ] ) ) { - return $file_data_option[ $key ]; - } - - $data = get_file_data( $file, $headers ); - - $file_data_option[ $key ] = $data; - - set_transient( $cache_key, $file_data_option, 29 * DAY_IN_SECONDS ); - - return $data; + return ( new Modules() )->get_file_data( $file, $headers ); } /** @@ -2651,36 +2403,7 @@ class Jetpack { * Get a list of activated modules as an array of module slugs. */ public static function get_active_modules() { - $active = Jetpack_Options::get_option( 'active_modules' ); - - if ( ! is_array( $active ) ) { - $active = array(); - } - - if ( class_exists( 'VaultPress' ) || function_exists( 'vaultpress_contact_service' ) ) { - $active[] = 'vaultpress'; - } else { - $active = array_diff( $active, array( 'vaultpress' ) ); - } - - // If protect is active on the main site of a multisite, it should be active on all sites. - if ( ! in_array( 'protect', $active ) && is_multisite() && get_site_option( 'jetpack_protect_active' ) ) { - $active[] = 'protect'; - } - - /** - * Allow filtering of the active modules. - * - * Gives theme and plugin developers the power to alter the modules that - * are activated on the fly. - * - * @since 5.8.0 - * - * @param array $active Array of active module slugs. - */ - $active = apply_filters( 'jetpack_active_modules', $active ); - - return array_unique( $active ); + return ( new Modules() )->get_active(); } /** @@ -2692,7 +2415,7 @@ class Jetpack { * @static */ public static function is_module_active( $module ) { - return in_array( $module, self::get_active_modules() ); + return ( new Modules() )->is_active( $module ); } /** @@ -2703,7 +2426,7 @@ class Jetpack { * @return bool */ public static function is_module( $module ) { - return ! empty( $module ) && ! validate_file( $module, self::get_available_modules() ); + return ( new Modules() )->is_module( $module ); } /** @@ -2714,17 +2437,7 @@ class Jetpack { * @static */ public static function catch_errors( $catch ) { - static $display_errors, $error_reporting; - - if ( $catch ) { - $display_errors = @ini_set( 'display_errors', 1 ); - $error_reporting = @error_reporting( E_ALL ); - add_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 0 ); - } else { - @ini_set( 'display_errors', $display_errors ); - @error_reporting( $error_reporting ); - remove_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 0 ); - } + return ( new Errors() )->catch_errors( $catch ); } /** @@ -2776,7 +2489,7 @@ class Jetpack { ) { $jetpack = self::init(); - if ( is_null( $redirect ) ) { + if ( $redirect === null ) { if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || @@ -2796,7 +2509,7 @@ class Jetpack { } } - if ( is_null( $send_state_messages ) ) { + if ( $send_state_messages === null ) { $send_state_messages = current_user_can( 'jetpack_activate_modules' ); } @@ -2866,11 +2579,12 @@ class Jetpack { continue; } - if ( $send_state_messages && in_array( $module, $active ) ) { + if ( $send_state_messages && in_array( $module, $active, true ) ) { $module_info = self::get_module( $module ); if ( ! $module_info['deactivate'] ) { - $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules'; - if ( $active_state = self::state( $state ) ) { + $state = in_array( $module, $other_modules, true ) ? 'reactivated_modules' : 'activated_modules'; + $active_state = self::state( $state ); + if ( $active_state ) { $active_state = explode( ',', $active_state ); } else { $active_state = array(); @@ -2903,8 +2617,9 @@ class Jetpack { if ( $send_state_messages ) { - $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules'; - if ( $active_state = self::state( $state ) ) { + $state = in_array( $module, $other_modules, true ) ? 'reactivated_modules' : 'activated_modules'; + $active_state = self::state( $state ); + if ( $active_state ) { $active_state = explode( ',', $active_state ); } else { $active_state = array(); @@ -2948,97 +2663,7 @@ class Jetpack { * @return bool|void */ public static function activate_module( $module, $exit = true, $redirect = true ) { - /** - * Fires before a module is activated. - * - * @since 2.6.0 - * - * @param string $module Module slug. - * @param bool $exit Should we exit after the module has been activated. Default to true. - * @param bool $redirect Should the user be redirected after module activation? Default to true. - */ - do_action( 'jetpack_pre_activate_module', $module, $exit, $redirect ); - - $jetpack = self::init(); - - if ( ! strlen( $module ) ) { - return false; - } - - if ( ! self::is_module( $module ) ) { - return false; - } - - // If it's already active, then don't do it again. - $active = self::get_active_modules(); - foreach ( $active as $act ) { - if ( $act == $module ) { - return true; - } - } - - $module_data = self::get_module( $module ); - - $is_offline_mode = ( new Status() )->is_offline_mode(); - if ( ! self::is_connection_ready() ) { - if ( ! $is_offline_mode && ! self::is_onboarding() ) { - return false; - } - - // If we're not connected but in offline mode, make sure the module doesn't require a connection. - if ( $is_offline_mode && $module_data['requires_connection'] ) { - return false; - } - } - - // Check and see if the old plugin is active. - if ( isset( $jetpack->plugins_to_deactivate[ $module ] ) ) { - // Deactivate the old plugin. - if ( Jetpack_Client_Server::deactivate_plugin( $jetpack->plugins_to_deactivate[ $module ][0], $jetpack->plugins_to_deactivate[ $module ][1] ) ) { - // If we deactivated the old plugin, remembere that with ::state() and redirect back to this page to activate the module - // We can't activate the module on this page load since the newly deactivated old plugin is still loaded on this page load. - self::state( 'deactivated_plugins', $module ); - wp_safe_redirect( add_query_arg( 'jetpack_restate', 1 ) ); - exit; - } - } - - // Protect won't work with mis-configured IPs. - if ( 'protect' === $module ) { - include_once JETPACK__PLUGIN_DIR . 'modules/protect/shared-functions.php'; - if ( ! jetpack_protect_get_ip() ) { - self::state( 'message', 'protect_misconfigured_ip' ); - return false; - } - } - - if ( ! Jetpack_Plan::supports( $module ) ) { - return false; - } - - // Check the file for fatal errors, a la wp-admin/plugins.php::activate. - self::state( 'module', $module ); - self::state( 'error', 'module_activation_failed' ); // we'll override this later if the plugin can be included without fatal error. - - self::catch_errors( true ); - ob_start(); - require self::get_module_path( $module ); - /** This action is documented in class.jetpack.php */ - do_action( 'jetpack_activate_module', $module ); - $active[] = $module; - self::update_active_modules( $active ); - - self::state( 'error', false ); // the override. - ob_end_clean(); - self::catch_errors( false ); - - if ( $redirect ) { - wp_safe_redirect( self::admin_url( 'page=jetpack' ) ); - } - if ( $exit ) { - exit; - } - return true; + return ( new Modules() )->activate( $module, $exit, $redirect ); } /** @@ -3049,21 +2674,7 @@ class Jetpack { * @return bool */ public static function deactivate_module( $module ) { - /** - * Fires when a module is deactivated. - * - * @since 1.9.0 - * - * @param string $module Module slug. - */ - do_action( 'jetpack_pre_deactivate_module', $module ); - - $jetpack = self::init(); - - $active = self::get_active_modules(); - $new = array_filter( array_diff( $active, (array) $module ) ); - - return self::update_active_modules( $new ); + return ( new Modules() )->deactivate( $module ); } /** @@ -3159,7 +2770,7 @@ p { Jetpack_Options::update_option( 'activated', 1 ); if ( version_compare( $GLOBALS['wp_version'], JETPACK__MINIMUM_WP_VERSION, '<' ) ) { - /* translator: Jetpack version number. */ + /* translators: Jetpack version number. */ self::bail_on_activation( sprintf( __( 'Jetpack requires WordPress version %s or later.', 'jetpack' ), JETPACK__MINIMUM_WP_VERSION ) ); } @@ -3285,7 +2896,8 @@ p { } if ( ! Jetpack_Options::get_option( 'version' ) ) { - $version = $old_version = JETPACK__VERSION . ':' . time(); + $old_version = JETPACK__VERSION . ':' . time(); + $version = $old_version; /** This action is documented in class.jetpack.php */ do_action( 'updating_jetpack_version', $version, false ); Jetpack_Options::update_options( compact( 'version', 'old_version' ) ); @@ -3357,6 +2969,10 @@ p { * Disconnects from the Jetpack servers. * Forgets all connection details and tells the Jetpack servers to do the same. * + * Will not disconnect if there are other plugins using the connection. + * + * @since 11.0 Do not disconnect if other plugins are using the connection. + * * @static */ public static function disconnect() { @@ -3365,7 +2981,7 @@ p { // If the site is in an IDC because sync is not allowed, // let's make sure to not disconnect the production site. - $connection->disconnect_site( ! Identity_Crisis::validate_sync_error_idc_option() ); + $connection->remove_connection( ! Identity_Crisis::validate_sync_error_idc_option() ); } /** @@ -3462,14 +3078,14 @@ p { 'code' => $code, ); // Don't bother storing it unless we've got some. - if ( ! is_null( $data ) ) { + if ( $data !== null ) { $log_entry['data'] = $data; } $log[] = $log_entry; // Try add_option first, to make sure it's not autoloaded. // @todo: Add an add_option method to Jetpack_Options. - if ( ! add_option( 'jetpack_log', $log, null, 'no' ) ) { + if ( ! add_option( 'jetpack_log', $log, '', 'no' ) ) { Jetpack_Options::update_option( 'log', $log ); } @@ -3568,7 +3184,7 @@ p { } if ( $encode ) { - return json_encode( $data ); + return wp_json_encode( $data ); } return $data; @@ -3582,6 +3198,7 @@ p { * @return array stats values. */ public static function get_additional_stat_data( $prefix = '' ) { + $return = array(); $return[ "{$prefix}themes" ] = self::get_parsed_theme_data(); $return[ "{$prefix}plugins-extra" ] = self::get_parsed_plugin_data(); $return[ "{$prefix}users" ] = (int) self::get_site_user_count(); @@ -3606,7 +3223,8 @@ p { return -1; // Not a real value but should tell us that we are dealing with a large network. } } - if ( false === ( $user_count = get_transient( 'jetpack_site_user_count' ) ) ) { + $user_count = get_transient( 'jetpack_site_user_count' ); + if ( false === ( $user_count ) ) { // It wasn't there, so regenerate the data and save the transient. $user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}capabilities'" ); set_transient( 'jetpack_site_user_count', $user_count, DAY_IN_SECONDS ); @@ -3623,7 +3241,7 @@ p { * * @return void */ - function admin_init() { + public function admin_init() { // If the plugin is not connected, display a connect message. if ( // the plugin was auto-activated and needs its candy. @@ -3686,7 +3304,7 @@ p { * * @return string */ - function admin_body_class( $admin_body_class = '' ) { + public function admin_body_class( $admin_body_class = '' ) { $classes = explode( ' ', trim( $admin_body_class ) ); $classes[] = self::is_connection_ready() ? 'jetpack-connected' : 'jetpack-disconnected'; @@ -3702,7 +3320,7 @@ p { * * @return string */ - static function add_jetpack_pagestyles( $admin_body_class = '' ) { + public static function add_jetpack_pagestyles( $admin_body_class = '' ) { return $admin_body_class . ' jetpack-pagestyles '; } @@ -3712,21 +3330,21 @@ p { * * @param string $plugin The activated plugin. */ - function throw_error_on_activate_plugin( $plugin ) { + public function throw_error_on_activate_plugin( $plugin ) { $active_modules = self::get_active_modules(); // The Shortlinks module and the Stats plugin conflict, but won't cause errors on activation because of some function_exists() checks. - if ( function_exists( 'stats_get_api_key' ) && in_array( 'shortlinks', $active_modules ) ) { + if ( function_exists( 'stats_get_api_key' ) && in_array( 'shortlinks', $active_modules, true ) ) { $throw = false; // Try and make sure it really was the stats plugin. if ( ! class_exists( 'ReflectionFunction' ) ) { - if ( 'stats.php' == basename( $plugin ) ) { + if ( 'stats.php' === basename( $plugin ) ) { $throw = true; } } else { $reflection = new ReflectionFunction( 'stats_get_api_key' ); - if ( basename( $plugin ) == basename( $reflection->getFileName() ) ) { + if ( basename( $plugin ) === basename( $reflection->getFileName() ) ) { $throw = true; } } @@ -3751,7 +3369,7 @@ p { * * @return void */ - function intercept_plugin_error_scrape_init() { + public function intercept_plugin_error_scrape_init() { add_action( 'check_admin_referer', array( $this, 'intercept_plugin_error_scrape' ), 10, 2 ); } @@ -3763,13 +3381,13 @@ p { * * @return void */ - function intercept_plugin_error_scrape( $action, $result ) { + public function intercept_plugin_error_scrape( $action, $result ) { if ( ! $result ) { return; } foreach ( $this->plugins_to_deactivate as $deactivate_me ) { - if ( "plugin-activation-error_{$deactivate_me[0]}" == $action ) { + if ( "plugin-activation-error_{$deactivate_me[0]}" === $action ) { /* translators: Plugin name to deactivate. */ self::bail_on_activation( sprintf( __( 'Jetpack contains the most recent version of the old “%1$s” plugin.', 'jetpack' ), $deactivate_me[1] ), false ); } @@ -3817,8 +3435,6 @@ p { * @access public */ public function remote_request_handlers() { - $action = current_filter(); - switch ( current_filter() ) { case 'wp_ajax_nopriv_jetpack_upload_file': $response = $this->upload_handler(); @@ -3846,7 +3462,7 @@ p { } status_header( $status_code ); - die( json_encode( (object) compact( 'error', 'error_description' ) ) ); + die( wp_json_encode( (object) compact( 'error', 'error_description' ) ) ); } status_header( 200 ); @@ -3854,7 +3470,7 @@ p { exit; } - die( json_encode( (object) $response ) ); + die( wp_json_encode( (object) $response ) ); } /** @@ -3866,7 +3482,7 @@ p { * @param boolean $update_media_item - update media attachment. * @return array - An array describing the uploadind files process. */ - function upload_handler( $update_media_item = false ) { + public function upload_handler( $update_media_item = false ) { if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) { return new WP_Error( 405, get_status_header_desc( 405 ), 405 ); } @@ -3899,6 +3515,23 @@ p { return new WP_Error( 'unknown_token', 'Unknown Jetpack token', 403 ); } + /** + * Optionally block uploads processed through Jetpack's upload_handler(). + * The filter may return false or WP_Error to block this particular upload. + * + * @since 10.8 + * + * @param bool|WP_Error $allowed If false or WP_Error, block the upload. If true, allow the upload. + * @param mixed $_FILES The $_FILES attempting to be uploaded. + */ + $can_upload = apply_filters( 'jetpack_upload_handler_can_upload', true, $_FILES ); + if ( ! $can_upload || is_wp_error( $can_upload ) ) { + if ( is_wp_error( $can_upload ) ) { + return $can_upload; + } + return new WP_Error( 'handler_cannot_upload', __( 'The upload handler cannot upload files', 'jetpack' ), 400 ); + } + $uploaded_files = array(); $global_post = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null; unset( $GLOBALS['post'] ); @@ -3926,12 +3559,13 @@ p { } if ( $update_media_item ) { - if ( ! isset( $post_id ) || $post_id === 0 ) { + if ( ! isset( $post_id ) || 0 === $post_id ) { return new WP_Error( 'invalid_input', 'Media ID must be defined.', 400 ); } $media_array = $_FILES['media']; + $file_array = array(); $file_array['name'] = $media_array['name'][0]; $file_array['type'] = $media_array['type'][0]; $file_array['tmp_name'] = $media_array['tmp_name'][0]; @@ -3985,7 +3619,7 @@ p { ); } } - if ( ! is_null( $global_post ) ) { + if ( $global_post !== null ) { $GLOBALS['post'] = $global_post; } @@ -3998,7 +3632,7 @@ p { * @since Jetpack (1.2.3) * @return void */ - function admin_help() { + public function admin_help() { $current_screen = get_current_screen(); // Overview. @@ -4047,50 +3681,16 @@ p { * * @return void */ - function admin_menu_css() { + public function admin_menu_css() { wp_enqueue_style( 'jetpack-icons' ); } /** - * Returns true. - * - * @todo This is seemingly unused. - * - * @return bool - */ - function admin_menu_order() { - return true; - } - - /** - * Sorts the order of wp-admin menu items. - * - * @param array $menu_order Existing menu order. - * - * @return array - */ - function jetpack_menu_order( $menu_order ) { - $jp_menu_order = array(); - - foreach ( $menu_order as $index => $item ) { - if ( $item != 'jetpack' ) { - $jp_menu_order[] = $item; - } - - if ( $index == 0 ) { - $jp_menu_order[] = 'jetpack'; - } - } - - return $jp_menu_order; - } - - /** * Registers/enqueues Jetpack banner styles. * * @return void */ - function admin_banner_styles() { + public function admin_banner_styles() { $min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; if ( ! wp_style_is( 'jetpack-dops-style' ) ) { @@ -4119,21 +3719,18 @@ p { * * @return array */ - function plugin_action_links( $actions ) { - - $jetpack_home = array( 'jetpack-home' => sprintf( '<a href="%s">%s</a>', self::admin_url( 'page=jetpack' ), __( 'My Jetpack', 'jetpack' ) ) ); + public function plugin_action_links( $actions ) { $support_link = ( new Host() )->is_woa_site() ? 'https://wordpress.com/help/contact/' : self::admin_url( 'page=jetpack-debugger' ); if ( current_user_can( 'jetpack_manage_modules' ) && ( self::is_connection_ready() || ( new Status() )->is_offline_mode() ) ) { return array_merge( - $jetpack_home, array( 'settings' => sprintf( '<a href="%s">%s</a>', self::admin_url( 'page=jetpack#/settings' ), __( 'Settings', 'jetpack' ) ) ), array( 'support' => sprintf( '<a href="%s">%s</a>', $support_link, __( 'Support', 'jetpack' ) ) ), $actions ); } - return array_merge( $jetpack_home, $actions ); + return $actions; } /** @@ -4170,7 +3767,7 @@ p { // Add objects to be passed to the initial state of the app. // Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280. - wp_add_inline_script( 'jetpack-plugins-page-js', 'var Initial_State=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( Jetpack_Redux_State_Helper::get_initial_state() ) ) . '"));', 'before' ); + wp_add_inline_script( 'jetpack-plugins-page-js', 'var Initial_State=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( Jetpack_Redux_State_Helper::get_minimal_state() ) ) . '"));', 'before' ); add_action( 'admin_footer', array( $this, 'jetpack_plugin_portal_containers' ) ); } @@ -4210,7 +3807,7 @@ p { public function login_init() { // phpcs:ignore WordPress.Security.NonceVerification if ( ! empty( $_GET[ self::$jetpack_redirect_login ] ) ) { - add_filter( 'allowed_redirect_hosts', array( &$this, 'allow_wpcom_environments' ) ); + add_filter( 'allowed_redirect_hosts', array( $this, 'allow_wpcom_environments' ) ); wp_safe_redirect( add_query_arg( array( @@ -4242,16 +3839,16 @@ p { * 4 - redirect to https://wordpress.com/start/jetpack-connect * 5 - user logs in with WP.com account * 6 - remote request to this site's xmlrpc.php with action remoteAuthorize, Jetpack_XMLRPC_Server->remote_authorize - * - Manager::authorize() - * - Manager::get_token() - * - GET https://jetpack.wordpress.com/jetpack.token/1/ with + * - Manager::authorize() + * - Manager::get_token() + * - GET https://jetpack.wordpress.com/jetpack.token/1/ with * client_id, client_secret, grant_type, code, redirect_uri:action=authorize, state, scope, user_email, user_login - * - which responds with access_token, token_type, scope - * - Manager::authorize() stores jetpack_options: user_token => access_token.$user_id - * - Jetpack::activate_default_modules() - * - Deactivates deprecated plugins - * - Activates all default modules - * - Responds with either error, or 'connected' for new connection, or 'linked' for additional linked users + * - which responds with access_token, token_type, scope + * - Manager::authorize() stores jetpack_options: user_token => access_token.$user_id + * - Jetpack::activate_default_modules() + * - Deactivates deprecated plugins + * - Activates all default modules + * - Responds with either error, or 'connected' for new connection, or 'linked' for additional linked users * 7 - For a new connection, user selects a Jetpack plan on wordpress.com * 8 - User is redirected back to wp-admin/index.php?page=jetpack with state:message=authorized * Done! @@ -4260,7 +3857,7 @@ p { /** * Handles the page load events for the Jetpack admin page */ - function admin_page_load() { + public function admin_page_load() { $error = false; // Make sure we have the right body class to hook stylings for subpages off of. @@ -4278,9 +3875,9 @@ p { if ( ! self::connection()->is_user_connected() ) { $redirect = ! empty( $_GET['redirect_after_auth'] ) ? $_GET['redirect_after_auth'] : false; - add_filter( 'allowed_redirect_hosts', array( &$this, 'allow_wpcom_environments' ) ); + add_filter( 'allowed_redirect_hosts', array( $this, 'allow_wpcom_environments' ) ); $connect_url = $this->build_connect_url( true, $redirect, $from ); - remove_filter( 'allowed_redirect_hosts', array( &$this, 'allow_wpcom_environments' ) ); + remove_filter( 'allowed_redirect_hosts', array( $this, 'allow_wpcom_environments' ) ); if ( isset( $_GET['notes_iframe'] ) ) { $connect_url .= '¬es_iframe'; @@ -4303,55 +3900,12 @@ p { if ( isset( $_GET['action'] ) ) { switch ( $_GET['action'] ) { + /** + * Cases authorize and authorize_redirect are now handled by Connection package Webhooks + */ case 'authorize_redirect': - self::log( 'authorize_redirect' ); - - add_filter( - 'allowed_redirect_hosts', - function ( $domains ) { - $domains[] = 'jetpack.com'; - $domains[] = 'jetpack.wordpress.com'; - $domains[] = 'wordpress.com'; - $domains[] = wp_parse_url( static::get_calypso_host(), PHP_URL_HOST ); // May differ from `wordpress.com`. - return array_unique( $domains ); - } - ); - - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $dest_url = empty( $_GET['dest_url'] ) ? null : $_GET['dest_url']; - - if ( ! $dest_url || ( 0 === stripos( $dest_url, 'https://jetpack.com/' ) && 0 === stripos( $dest_url, 'https://wordpress.com/' ) ) ) { - // The destination URL is missing or invalid, nothing to do here. - exit; - } - - if ( static::connection()->is_connected() && static::connection()->is_user_connected() ) { - // The user is either already connected, or finished the connection process. - wp_safe_redirect( $dest_url ); - exit; - } elseif ( ! empty( $_GET['done'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - // The user decided not to proceed with setting up the connection. - wp_safe_redirect( self::admin_url( 'page=jetpack' ) ); - exit; - } - - $redirect_args = array( - 'page' => 'jetpack', - 'action' => 'authorize_redirect', - 'dest_url' => rawurlencode( $dest_url ), - 'done' => '1', - ); - - if ( ! empty( $_GET['from'] ) && 'jetpack_site_only_checkout' === $_GET['from'] ) { - $redirect_args['from'] = 'jetpack_site_only_checkout'; - } - - wp_safe_redirect( static::build_authorize_url( self::admin_url( $redirect_args ) ) ); - exit; case 'authorize': - _doing_it_wrong( __METHOD__, 'The `page=jetpack&action=authorize` webhook is deprecated. Use `handler=jetpack-connection-webhooks&action=authorize` instead', 'Jetpack 9.5.0' ); - ( new Connection_Webhooks( $this->connection_manager ) )->handle_authorize(); - exit; + break; case 'register': if ( ! current_user_can( 'jetpack_connect' ) ) { $error = 'cheatin'; @@ -4488,7 +4042,9 @@ p { self::create_onboarding_token(); $url = $this->build_connect_url( true ); - if ( false !== ( $token = Jetpack_Options::get_option( 'onboarding' ) ) ) { + $token = Jetpack_Options::get_option( 'onboarding' ); + + if ( false !== ( $token ) ) { $url = add_query_arg( 'onboarding', $token, $url ); } @@ -4513,7 +4069,8 @@ p { } } - if ( ! $error = $error ? $error : self::state( 'error' ) ) { + $error = $error ? $error : self::state( 'error' ); + if ( ! $error ) { self::activate_new_modules( true ); } @@ -4588,7 +4145,7 @@ p { * * @return void */ - function admin_notices() { + public function admin_notices() { if ( $this->error ) { ?> @@ -4609,7 +4166,10 @@ p { ); ?> </h2> - <?php if ( $desc = self::state( 'error_description' ) ) : ?> + <?php + $desc = self::state( 'error_description' ); + if ( $desc ) : + ?> <p><?php echo esc_html( stripslashes( $desc ) ); ?></p> <?php endif; ?> </div> @@ -4639,7 +4199,8 @@ p { } if ( $this->privacy_checks ) : - $module_names = $module_slugs = array(); + $module_names = array(); + $module_slugs = array(); $privacy_checks = explode( ',', $this->privacy_checks ); $privacy_checks = array_filter( $privacy_checks, array( 'Jetpack', 'is_module' ) ); @@ -4693,7 +4254,7 @@ p { array( 'page' => 'jetpack', 'action' => 'deactivate', - 'module' => urlencode( $module_slugs ), + 'module' => rawurlencode( $module_slugs ), ) ), "jetpack_deactivate-$module_slugs" @@ -4728,7 +4289,7 @@ endif; * @param WP_Error $xmlrpc_error The error produced during * signature validation. */ - function track_xmlrpc_error( $xmlrpc_error ) { + public function track_xmlrpc_error( $xmlrpc_error ) { $code = is_wp_error( $xmlrpc_error ) ? $xmlrpc_error->get_error_code() : 'should-not-happen'; @@ -4750,7 +4311,7 @@ endif; * @return void */ private function initialize_stats() { - if ( is_null( $this->a8c_mc_stats_instance ) ) { + if ( $this->a8c_mc_stats_instance === null ) { $this->a8c_mc_stats_instance = new Automattic\Jetpack\A8c_Mc_Stats(); } } @@ -4761,7 +4322,7 @@ endif; * @param string $group Stats group. * @param string $detail Stats detail. */ - function stat( $group, $detail ) { + public function stat( $group, $detail ) { $this->initialize_stats(); $this->a8c_mc_stats_instance->add( $group, $detail ); @@ -4774,7 +4335,7 @@ endif; * * @param string $method Used to check if method is "server-side". */ - function do_stats( $method = '' ) { + public function do_stats( $method = '' ) { $this->initialize_stats(); if ( 'server_side' === $method ) { $this->a8c_mc_stats_instance->do_server_side_stats(); @@ -4793,7 +4354,7 @@ endif; * * @return bool If it worked. */ - static function do_server_side_stat( $args ) { + public static function do_server_side_stat( $args ) { $url = self::build_stats_url( $args ); $a8c_mc_stats_instance = new Automattic\Jetpack\A8c_Mc_Stats(); return $a8c_mc_stats_instance->do_server_side_stat( $url ); @@ -4806,7 +4367,7 @@ endif; * * @return string The URL to be pinged. */ - static function build_stats_url( $args ) { + public static function build_stats_url( $args ) { $a8c_mc_stats_instance = new Automattic\Jetpack\A8c_Mc_Stats(); return $a8c_mc_stats_instance->build_stats_url( $args ); @@ -4826,7 +4387,7 @@ endif; * * @return string Connect URL */ - function build_connect_url( $raw = false, $redirect = false, $from = false, $register = false ) { + public function build_connect_url( $raw = false, $redirect = false, $from = false, $register = false ) { $site_id = Jetpack_Options::get_option( 'id' ); $blog_token = ( new Tokens() )->get_access_token(); @@ -4836,7 +4397,7 @@ endif; if ( ! empty( $redirect ) ) { $url = add_query_arg( 'redirect', - urlencode( wp_validate_redirect( esc_url_raw( $redirect ) ) ), + rawurlencode( wp_validate_redirect( esc_url_raw( $redirect ) ) ), $url ); } @@ -4893,31 +4454,23 @@ endif; * Create the Jetpack authorization URL. * * @param bool|string $redirect URL to redirect to. - * @param bool $iframe Whether to use the iframe version. + * @param null $deprecated Deprecated since Jetpack 10.9. * * @todo Update default value for redirect since the called function expects a string. * * @return mixed|void */ - public static function build_authorize_url( $redirect = false, $iframe = false ) { + public static function build_authorize_url( $redirect = false, $deprecated = null ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable add_filter( 'jetpack_connect_request_body', array( __CLASS__, 'filter_connect_request_body' ) ); add_filter( 'jetpack_connect_redirect_url', array( __CLASS__, 'filter_connect_redirect_url' ) ); - if ( $iframe ) { - add_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); - } - $c8n = self::connection(); $url = $c8n->get_authorization_url( wp_get_current_user(), $redirect ); remove_filter( 'jetpack_connect_request_body', array( __CLASS__, 'filter_connect_request_body' ) ); remove_filter( 'jetpack_connect_redirect_url', array( __CLASS__, 'filter_connect_redirect_url' ) ); - if ( $iframe ) { - remove_filter( 'jetpack_use_iframe_authorization_flow', '__return_true' ); - } - /** * Filter the URL used when authorizing a user to a WordPress.com account. * @@ -5151,11 +4704,11 @@ endif; list( $activation_source_name, $activation_source_keyword ) = get_option( 'jetpack_activation_source' ); if ( $activation_source_name ) { - $args['_as'] = urlencode( $activation_source_name ); + $args['_as'] = rawurlencode( $activation_source_name ); } if ( $activation_source_keyword ) { - $args['_ak'] = urlencode( $activation_source_keyword ); + $args['_ak'] = rawurlencode( $activation_source_keyword ); } } @@ -5166,7 +4719,7 @@ endif; * * @return string|null */ - function build_reconnect_url( $raw = false ) { + public function build_reconnect_url( $raw = false ) { $url = wp_nonce_url( self::admin_url( 'action=reconnect' ), 'jetpack-reconnect' ); return $raw ? $url : esc_url( $url ); } @@ -5179,9 +4732,7 @@ endif; * @return string Jetpack admin URL. */ public static function admin_url( $args = null ) { - $args = wp_parse_args( $args, array( 'page' => 'jetpack' ) ); - $url = add_query_arg( $args, admin_url( 'admin.php' ) ); - return $url; + return ( new Paths() )->admin_url( $args ); } /** @@ -5203,7 +4754,7 @@ endif; * * @return void */ - function dismiss_jetpack_notice() { + public function dismiss_jetpack_notice() { if ( ! isset( $_GET['jetpack-notice'] ) ) { return; } @@ -5229,7 +4780,7 @@ endif; * @return int 0 if the same sort or (+/-) to indicate which is greater. */ public static function sort_modules( $a, $b ) { - if ( $a['sort'] == $b['sort'] ) { + if ( $a['sort'] === $b['sort'] ) { return 0; } @@ -5243,7 +4794,7 @@ endif; * * @return void */ - function ajax_recheck_ssl() { + public function ajax_recheck_ssl() { check_ajax_referer( 'recheck-ssl', 'ajax-nonce' ); $result = self::permit_ssl( true ); wp_send_json( @@ -5317,7 +4868,8 @@ endif; * @return string Secret token */ public static function create_onboarding_token() { - if ( false === ( $token = Jetpack_Options::get_option( 'onboarding' ) ) ) { + $token = Jetpack_Options::get_option( 'onboarding' ); + if ( false === ( $token ) ) { $token = wp_generate_password( 32, false ); Jetpack_Options::update_option( 'onboarding', $token ); } @@ -5354,7 +4906,7 @@ endif; ); // Only allow valid actions. - if ( ! in_array( $action, $valid_actions ) ) { + if ( ! in_array( $action, $valid_actions, true ) ) { return false; } @@ -5371,7 +4923,11 @@ endif; */ public static function permit_ssl( $force_recheck = false ) { // Do some fancy tests to see if ssl is being supported. - if ( $force_recheck || false === ( $ssl = get_transient( 'jetpack_https_test' ) ) ) { + if ( ! $force_recheck ) { + $ssl = get_transient( 'jetpack_https_test' ); + } + + if ( $force_recheck || false === $ssl ) { $message = ''; if ( 'https' !== substr( JETPACK__API_BASE, 0, 5 ) ) { $ssl = 0; @@ -5438,7 +4994,7 @@ endif; jQuery( document ).ready( function( $ ) { $( '#jetpack-recheck-ssl-button' ).click( function( e ) { var $this = $( this ); - $this.html( <?php echo json_encode( __( 'Checking', 'jetpack' ) ); ?> ); + $this.html( <?php echo wp_json_encode( __( 'Checking', 'jetpack' ) ); ?> ); $( '#jetpack-recheck-ssl-output' ).html( '' ); e.preventDefault(); var data = { action: 'jetpack-recheck-ssl', 'ajax-nonce': '<?php echo $ajax_nonce; ?>' }; @@ -5544,7 +5100,7 @@ endif; /** * Filters the token request body to include tracking properties. * - * @param array $properties + * @param array $properties Token request properties. * * @return array amended properties. */ @@ -5606,60 +5162,7 @@ endif; * @param bool $restate Reset the cookie (private). */ public static function state( $key = null, $value = null, $restate = false ) { - static $state = array(); - static $path, $domain; - if ( ! isset( $path ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - $admin_url = self::admin_url(); - $bits = wp_parse_url( $admin_url ); - - if ( is_array( $bits ) ) { - $path = ( isset( $bits['path'] ) ) ? dirname( $bits['path'] ) : null; - $domain = ( isset( $bits['host'] ) ) ? $bits['host'] : null; - } else { - $path = $domain = null; - } - } - - // Extract state from cookies and delete cookies. - if ( isset( $_COOKIE['jetpackState'] ) && is_array( $_COOKIE['jetpackState'] ) ) { - $yum = wp_unslash( $_COOKIE['jetpackState'] ); - unset( $_COOKIE['jetpackState'] ); - foreach ( $yum as $k => $v ) { - if ( strlen( $v ) ) { - $state[ $k ] = $v; - } - setcookie( "jetpackState[$k]", false, 0, $path, $domain ); - } - } - - if ( $restate ) { - foreach ( $state as $k => $v ) { - setcookie( "jetpackState[$k]", $v, 0, $path, $domain ); - } - return; - } - - // Get a state variable. - if ( isset( $key ) && ! isset( $value ) ) { - if ( array_key_exists( $key, $state ) ) { - return $state[ $key ]; - } - return null; - } - - // Set a state variable. - if ( isset( $key ) && isset( $value ) ) { - if ( is_array( $value ) && isset( $value[0] ) ) { - $value = $value[0]; - } - $state[ $key ] = $value; - if ( ! headers_sent() ) { - if ( self::should_set_cookie( $key ) ) { - setcookie( "jetpackState[$key]", $value, 0, $path, $domain ); - } - } - } + return ( new CookieState() )->state( $key, $value, $restate ); } /** @@ -5680,14 +5183,7 @@ endif; * @return boolean Whether the value should be added to the cookie. */ public static function should_set_cookie( $key ) { - global $current_screen; - $page = isset( $current_screen->base ) ? $current_screen->base : null; - - if ( 'toplevel_page_jetpack' === $page && 'display_update_modal' === $key ) { - return false; - } - - return true; + return ( new CookieState() )->should_set_cookie( $key ); } /** @@ -5700,7 +5196,7 @@ endif; public static function check_privacy( $file ) { static $is_site_publicly_accessible = null; - if ( is_null( $is_site_publicly_accessible ) ) { + if ( $is_site_publicly_accessible === null ) { $is_site_publicly_accessible = false; $rpc = new Jetpack_IXR_Client(); @@ -5749,14 +5245,14 @@ endif; /** * Handles the login action for Authorizing the JSON API */ - function login_form_json_api_authorization() { + public function login_form_json_api_authorization() { $this->verify_json_api_authorization_request(); - add_action( 'wp_login', array( &$this, 'store_json_api_authorization_token' ), 10, 2 ); + add_action( 'wp_login', array( $this, 'store_json_api_authorization_token' ), 10, 2 ); - add_action( 'login_message', array( &$this, 'login_message_json_api_authorization' ) ); - add_action( 'login_form', array( &$this, 'preserve_action_in_login_form_for_json_api_authorization' ) ); - add_filter( 'site_url', array( &$this, 'post_login_form_to_signed_url' ), 10, 3 ); + add_action( 'login_message', array( $this, 'login_message_json_api_authorization' ) ); + add_action( 'login_form', array( $this, 'preserve_action_in_login_form_for_json_api_authorization' ) ); + add_filter( 'site_url', array( $this, 'post_login_form_to_signed_url' ), 10, 3 ); } /** @@ -5766,7 +5262,7 @@ endif; * @param string $path Path. * @param string $scheme URL Scheme. */ - function post_login_form_to_signed_url( $url, $path, $scheme ) { + public function post_login_form_to_signed_url( $url, $path, $scheme ) { if ( 'wp-login.php' !== $path || ( 'login_post' !== $scheme && 'login' !== $scheme ) ) { return $url; } @@ -5784,7 +5280,7 @@ endif; /** * Make sure the POSTed request is handled by the same action. */ - function preserve_action_in_login_form_for_json_api_authorization() { + public function preserve_action_in_login_form_for_json_api_authorization() { echo "<input type='hidden' name='action' value='jetpack_json_api_authorization' />\n"; echo "<input type='hidden' name='jetpack_json_api_original_query' value='" . esc_url( set_url_scheme( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) . "' />\n"; } @@ -5795,9 +5291,9 @@ endif; * @param string $user_login Unused. * @param WP_User $user User logged in. */ - function store_json_api_authorization_token( $user_login, $user ) { - add_filter( 'login_redirect', array( &$this, 'add_token_to_login_redirect_json_api_authorization' ), 10, 3 ); - add_filter( 'allowed_redirect_hosts', array( &$this, 'allow_wpcom_public_api_domain' ) ); + public function store_json_api_authorization_token( $user_login, $user ) { + add_filter( 'login_redirect', array( $this, 'add_token_to_login_redirect_json_api_authorization' ), 10, 3 ); + add_filter( 'allowed_redirect_hosts', array( $this, 'allow_wpcom_public_api_domain' ) ); $token = wp_generate_password( 32, false ); update_user_meta( $user->ID, 'jetpack_json_api_' . $this->json_api_authorization_request['client_id'], $token ); } @@ -5809,7 +5305,7 @@ endif; * * @param array $domains Allowed WP.com Environments. */ - function allow_wpcom_public_api_domain( $domains ) { + public function allow_wpcom_public_api_domain( $domains ) { $domains[] = 'public-api.wordpress.com'; return $domains; } @@ -5821,7 +5317,7 @@ endif; * * @return bool If redirect has been encoded. */ - static function is_redirect_encoded( $redirect_url ) { + public static function is_redirect_encoded( $redirect_url ) { return preg_match( '/https?%3A%2F%2F/i', $redirect_url ) > 0; } @@ -5832,7 +5328,7 @@ endif; * * @param array $domains Allowed WP.com Environments. */ - function allow_wpcom_environments( $domains ) { + public function allow_wpcom_environments( $domains ) { $domains[] = 'wordpress.com'; $domains[] = 'wpcalypso.wordpress.com'; $domains[] = 'horizon.wordpress.com'; @@ -5849,7 +5345,7 @@ endif; * * @return string */ - function add_token_to_login_redirect_json_api_authorization( $redirect_to, $original_redirect_to, $user ) { + public function add_token_to_login_redirect_json_api_authorization( $redirect_to, $original_redirect_to, $user ) { return add_query_arg( urlencode_deep( array( @@ -5870,8 +5366,8 @@ endif; * * @param null|array $environment Value to override $_REQUEST. */ - function verify_json_api_authorization_request( $environment = null ) { - $environment = is_null( $environment ) + public function verify_json_api_authorization_request( $environment = null ) { + $environment = $environment === null ? $_REQUEST : $environment; @@ -5958,7 +5454,7 @@ endif; } } - $data = json_decode( base64_decode( stripslashes( $environment['data'] ) ) ); + $data = json_decode( base64_decode( stripslashes( $environment['data'] ) ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode $data_filters = array( 'state' => 'opaque', 'client_id' => 'int', @@ -5995,11 +5491,9 @@ endif; /** * HTML for the JSON API authorization notice. * - * @param string $message Authorization message. Unused. - * * @return string */ - function login_message_json_api_authorization( $message ) { + public function login_message_json_api_authorization() { return '<p class="message">' . sprintf( /* translators: Name/image of the client requesting authorization */ esc_html__( '%s wants to access your site’s data. Log in to authorize that access.', 'jetpack' ), @@ -6156,7 +5650,7 @@ endif; $file_name_parts_r = array_reverse( explode( '.', $file_name ) ); $extension = array_shift( $file_name_parts_r ); - if ( in_array( strtolower( $extension ), array( 'css', 'js' ) ) ) { + if ( in_array( strtolower( $extension ), array( 'css', 'js' ), true ) ) { // Already pointing at the minified version. if ( 'min' === $file_name_parts_r[0] ) { return $url; @@ -6227,11 +5721,13 @@ endif; if ( preg_match( '# href=\'([^\']+)\' #i', $tag, $matches ) ) { $href = $matches[1]; // Strip off query string. - if ( $pos = strpos( $href, '?' ) ) { + $pos = strpos( $href, '?' ); + if ( $pos ) { $href = substr( $href, 0, $pos ); } // Strip off fragment. - if ( $pos = strpos( $href, '#' ) ) { + $pos = strpos( $href, '#' ); + if ( $pos ) { $href = substr( $href, 0, $pos ); } } else { @@ -6239,7 +5735,7 @@ endif; } $plugins_dir = plugin_dir_url( JETPACK__PLUGIN_FILE ); - if ( $plugins_dir !== substr( $href, 0, strlen( $plugins_dir ) ) ) { + if ( substr( $href, 0, strlen( $plugins_dir ) ) !== $plugins_dir ) { return $tag; } @@ -6277,7 +5773,7 @@ endif; * @param array $data - Any data to pass along to the template. * @return boolean - If template file was found. **/ - public function load_view( $template, $data = array() ) { + public function load_view( $template, $data = array() ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- This is used via the required files. $views_dir = JETPACK__PLUGIN_DIR . 'views/'; if ( file_exists( $views_dir . $template ) ) { @@ -6285,7 +5781,9 @@ endif; return true; } - error_log( "Jetpack: Unable to find view file $views_dir$template" ); + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + trigger_error( sprintf( 'Jetpack: Unable to find view file: %s', esc_html( $views_dir . $template ) ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error + } return false; } @@ -6488,6 +5986,18 @@ endif; 'replacement' => null, 'version' => 'jetpack-9.1.0', ), + 'sharing_email_can_send' => array( + 'replacement' => null, + 'version' => 'jetpack-11.0.0', + ), + 'sharing_email_check' => array( + 'replacement' => null, + 'version' => 'jetpack-11.0.0', + ), + 'sharing_services_email' => array( + 'replacement' => null, + 'version' => 'jetpack-11.0.0', + ), ); foreach ( $filter_deprecated_list as $tag => $args ) { @@ -6541,6 +6051,14 @@ endif; 'replacement' => null, 'version' => 'jetpack-8.3.0', ), + 'sharing_email_dialog' => array( + 'replacement' => null, + 'version' => 'jetpack-11.0.0', + ), + 'sharing_email_send_post' => array( + 'replacement' => null, + 'version' => 'jetpack-11.0.0', + ), ); foreach ( $action_deprecated_list as $tag => $args ) { @@ -6578,7 +6096,8 @@ endif; ); if ( preg_match_all( $pattern, $css, $matches, PREG_SET_ORDER ) ) { - $find = $replace = array(); + $replace = array(); + $find = array(); foreach ( $matches as $match ) { $url = trim( $match['path'], "'\" \t" ); @@ -6704,8 +6223,8 @@ endif; * * @return string */ - function concat_remove_style_loader_tag( $tag, $handle ) { - if ( in_array( $handle, $this->concatenated_style_handles ) ) { + public function concat_remove_style_loader_tag( $tag, $handle ) { + if ( in_array( $handle, $this->concatenated_style_handles, true ) ) { $tag = ''; if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { $tag = '<!-- `' . esc_html( $handle ) . "` is included in the concatenated jetpack.css -->\r\n"; @@ -6738,7 +6257,7 @@ endif; foreach ( $raw_data as $stat => $value ) { // Check jetpack version. - if ( 'version' == $stat ) { + if ( 'version' === $stat ) { if ( version_compare( $value, JETPACK__VERSION, '<' ) ) { $caution[ $stat ] = $value . ' - min supported is ' . JETPACK__VERSION; continue; @@ -6746,7 +6265,7 @@ endif; } // Check WP version. - if ( 'wp-version' == $stat ) { + if ( 'wp-version' === $stat ) { if ( version_compare( $value, JETPACK__MINIMUM_WP_VERSION, '<' ) ) { $caution[ $stat ] = $value . ' - min supported is ' . JETPACK__MINIMUM_WP_VERSION; continue; @@ -6754,7 +6273,7 @@ endif; } // Check PHP version. - if ( 'php-version' == $stat ) { + if ( 'php-version' === $stat ) { if ( version_compare( PHP_VERSION, JETPACK__MINIMUM_PHP_VERSION, '<' ) ) { $caution[ $stat ] = $value . ' - min supported is ' . JETPACK__MINIMUM_PHP_VERSION; continue; @@ -6762,8 +6281,8 @@ endif; } // Check ID crisis. - if ( 'identitycrisis' == $stat ) { - if ( 'yes' == $value ) { + if ( 'identitycrisis' === $stat ) { + if ( 'yes' === $value ) { $bad[ $stat ] = $value; continue; } @@ -6817,7 +6336,7 @@ endif; * @param array $sorted Value for the user's option. * @return mixed */ - function get_user_option_meta_box_order_dashboard( $sorted ) { + public function get_user_option_meta_box_order_dashboard( $sorted ) { if ( ! is_array( $sorted ) ) { return $sorted; } @@ -6829,7 +6348,7 @@ endif; } $ids_array = explode( ',', $ids ); - $key = array_search( 'dashboard_stats', $ids_array ); + $key = array_search( 'dashboard_stats', $ids_array, true ); if ( false !== $key ) { // If we've found that exact value in the option (and not `google_dashboard_stats` for example). @@ -6850,7 +6369,7 @@ endif; * * @return array */ - function jetpack_icon_user_connected( $columns ) { + public function jetpack_icon_user_connected( $columns ) { $columns['user_jetpack'] = ''; return $columns; } @@ -6864,7 +6383,7 @@ endif; * * @return string */ - function jetpack_show_user_connected_icon( $val, $col, $user_id ) { + public function jetpack_show_user_connected_icon( $val, $col, $user_id ) { if ( 'user_jetpack' === $col && self::connection()->is_user_connected( $user_id ) ) { $jetpack_logo = new Jetpack_Logo(); $emblem_html = sprintf( @@ -6881,9 +6400,9 @@ endif; /** * Style the Jetpack user column */ - function jetpack_user_col_style() { + public function jetpack_user_col_style() { global $current_screen; - if ( ! empty( $current_screen->base ) && 'users' == $current_screen->base ) { + if ( ! empty( $current_screen->base ) && 'users' === $current_screen->base ) { ?> <style> .fixed .column-user_jetpack { @@ -6915,7 +6434,7 @@ endif; public static function is_akismet_active() { static $status = null; - if ( ! is_null( $status ) ) { + if ( $status !== null ) { return $status; } @@ -7001,8 +6520,8 @@ endif; * @return string Calypso environment */ public static function get_calypso_env() { - if ( isset( $_GET['calypso_env'] ) ) { - return sanitize_key( $_GET['calypso_env'] ); + if ( isset( $_GET['calypso_env'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required; only used for changing environments. + return sanitize_key( $_GET['calypso_env'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required; only used for changing environments. } if ( getenv( 'CALYPSO_ENV' ) ) { @@ -7056,7 +6575,7 @@ endif; : array(); if ( Jetpack_Options::get_option( 'active_modules_initialized' ) ) { - $active_modules = Jetpack_Options::get_option( 'active_modules' ); + $active_modules = self::get_active_modules(); self::delete_active_modules(); self::activate_default_modules( 999, 1, array_merge( $active_modules, $other_modules ), $redirect_on_activation_error, $send_state_messages ); @@ -7171,6 +6690,7 @@ endif; _x( 'Automated daily scanning', 'Scan Product Feature', 'jetpack' ), _x( 'One-click fixes for most issues', 'Scan Product Feature', 'jetpack' ), _x( 'Instant email notifications', 'Scan Product Feature', 'jetpack' ), + _x( 'Access to latest Firewall rules', 'Scan Product Feature', 'jetpack' ), ), ); @@ -7256,7 +6776,7 @@ endif; /** * Register product descriptions for partner coupon usage. * - * @since $$next_version$$ + * @since 10.4.0 * * @param array $products An array of registered products. * |