PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.5
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.5
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | class.jetpack.php +18 -204 16.3-a.3 → 16.3-a.5 View file →
@@ -21,8 +21,9 @@
21 21 use Automattic\Jetpack\CookieState;
22 22 use Automattic\Jetpack\Current_Plan as Jetpack_Plan;
23 23 use Automattic\Jetpack\Device_Detection\User_Agent_Info;
24 24 use Automattic\Jetpack\Errors;
25 +use Automattic\Jetpack\Feature_Policy;
25 26 use Automattic\Jetpack\Files;
26 27 use Automattic\Jetpack\Heartbeat;
27 28 use Automattic\Jetpack\Identity_Crisis;
28 29 use Automattic\Jetpack\Import\Main as Import_Main;
@@ -79,20 +80,8 @@
79 80 * The Jetpack class.
80 81 */
81 82 class Jetpack {
82 83 /**
83 - * Marks that the durable Jetpack SEO module-state options have been reconciled against
84 - * the site's module configuration, so the repair runs at most once.
85 - *
86 - * {@see self::reconcile_seo_module_state_options()}
87 - *
88 - * @since 16.1
89 - *
90 - * @var string
91 - */
92 - const SEO_MODULE_STATE_RECONCILED_OPTION = 'jetpack_seo_module_state_reconciled';
93 -
94 - /**
95 84 * XMLRPC server instance.
96 85 *
97 86 * @var null|Jetpack_XMLRPC_Server XMLRPC server used by Jetpack.
98 87 */
@@ -555,8 +544,11 @@
555 544 if ( false === get_option( 'wpcom_newsletter_send_default' ) ) {
556 545 add_option( 'wpcom_newsletter_send_default', 1 );
557 546 }
558 547
548 + // Its handler went with the Recommendations assistant.
549 + wp_clear_scheduled_hook( 'jetpack_recommend_videopress' );
550 +
559 551 if ( did_action( 'wp_loaded' ) ) {
560 552 self::upgrade_on_load();
561 553 } else {
562 554 add_action(
@@ -784,11 +776,8 @@
784 776
785 777 // Register product descriptions for partner coupon usage.
786 778 add_filter( 'jetpack_partner_coupon_products', array( $this, 'get_partner_coupon_product_descriptions' ) );
787 779
788 - // Actions for conditional recommendations.
789 - add_action( 'plugins_loaded', array( 'Jetpack_Recommendations', 'init_conditional_recommendation_actions' ) );
790 -
791 780 // Add 5-star
792 781 add_filter( 'plugin_row_meta', array( $this, 'add_5_star_review_link' ), 10, 2 );
793 782 add_action( 'init', array( Deprecate::class, 'instance' ) );
794 783
@@ -1285,8 +1274,9 @@
1285 1274 $jetpack_callables = array(
1286 1275 'single_user_site' => array( 'Jetpack', 'is_single_user_site' ),
1287 1276 'updates' => array( 'Jetpack', 'get_updates' ),
1288 1277 'available_jetpack_blocks' => array( 'Jetpack_Gutenberg', 'get_availability' ), // Includes both Gutenberg blocks *and* plugins.
1278 + 'theme_styles' => array( 'Automattic\\Jetpack\\Plugin\\Theme_Styles_Sync', 'get_theme_styles' ),
1289 1279 );
1290 1280 return array_merge( $callables, $jetpack_callables );
1291 1281 }
1292 1282
@@ -2341,8 +2331,12 @@
2341 2331 default:
2342 2332 break;
2343 2333 }
2344 2334 }
2335 + if ( method_exists( Feature_Policy::class, 'ensure_hooks' ) ) {
2336 + Feature_Policy::ensure_hooks();
2337 + }
2338 +
2345 2339 /**
2346 2340 * Filters the array of default modules.
2347 2341 *
2348 2342 * @since 2.5.0
@@ -2838,9 +2832,9 @@
2838 2832 * @return string $url module configuration URL.
2839 2833 */
2840 2834 public static function module_configuration_url( $module ) {
2841 2835 $module = self::get_module_slug( $module );
2842 - $default_url = self::admin_url() . "#/settings?term=$module";
2836 + $default_url = self::admin_url( array( 'page' => 'jetpack-settings' ) ) . "#/settings?term=$module";
2843 2837 /**
2844 2838 * Allows to modify configure_url of specific module to be able to redirect to some custom location.
2845 2839 *
2846 2840 * @since 6.9.0
@@ -3116,199 +3110,19 @@
3116 3110 update_option( self::AI_MASTER_OPTOUT_MIGRATED_OPTION, true );
3117 3111 }
3118 3112
3119 3113 /**
3120 - * Whether a module should be recorded as active in its durable Jetpack SEO option.
3114 + * Deletes obsolete SEO module-state options without changing module activation.
3121 3115 *
3122 - * Permanent module overrides are part of the site's configuration, so the normal
3123 - * filtered module state is authoritative. The exception is wpcomsh's private-site
3124 - * callback, which temporarily suppresses `sitemaps` on Atomic sites without changing
3125 - * the site's configured state. Evaluate the module state with only that callback
3126 - * disabled.
3127 - *
3128 - * The hook is cloned before removing the callback so its ordering remains unchanged for
3129 - * the rest of the request. `$available_only` is false because these migrations can run
3130 - * after the standalone module file has been removed.
3131 - *
3132 - * WordPress.com Simple keeps module state outside this site's options table, so its
3133 - * normal filtered read remains authoritative.
3134 - *
3135 - * @since 16.1
3136 - *
3137 - * @param string $module Module slug.
3138 - * @return bool Whether the module should be recorded as active.
3116 + * @since 16.3
3139 3117 */
3140 - private static function is_module_active_for_seo_option( $module ) {
3141 - $modules = new Modules();
3142 -
3143 - if ( ( new Host() )->is_wpcom_simple() ) {
3144 - return $modules->is_active( $module, false );
3145 - }
3146 -
3147 - global $wp_filter;
3148 -
3149 - $hook_name = 'jetpack_active_modules';
3150 - $private_site_callback = '\Private_Site\filter_jetpack_active_modules';
3151 - $callback_priority = has_filter( $hook_name, $private_site_callback );
3152 -
3153 - if ( false === $callback_priority ) {
3154 - return $modules->is_active( $module, false );
3155 - }
3156 -
3157 - $original_hook = $wp_filter[ $hook_name ];
3158 - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Use an isolated hook copy without changing callback order.
3159 - $wp_filter[ $hook_name ] = clone $original_hook;
3160 - remove_filter( $hook_name, $private_site_callback, $callback_priority );
3161 -
3162 - try {
3163 - return $modules->is_active( $module, false );
3164 - } finally {
3165 - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Restore the untouched original hook.
3166 - $wp_filter[ $hook_name ] = $original_hook;
3167 - }
3118 + public static function cleanup_seo_module_state_options() {
3119 + delete_option( 'jetpack_seo_sitemap_enabled' );
3120 + delete_option( 'jetpack_seo_canonical_urls_enabled' );
3121 + delete_option( 'jetpack_seo_module_state_reconciled' );
3168 3122 }
3169 3123
3170 3124 /**
3171 - * Records whether the standalone Sitemaps module is active so the setting survives
3172 - * the module's removal.
3173 - *
3174 - * The Jetpack SEO product reads the {@see Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION}
3175 - * option instead of the `sitemaps` module's active state. Module-active state is
3176 - * filtered against the modules present on disk, so once the standalone module is
3177 - * removed it would read as inactive even for sites that had it on. This one-time
3178 - * migration captures the configured module state — which persists regardless of
3179 - * whether the module file is present — into the durable option.
3180 - *
3181 - * Deliberately non-destructive: it never touches generated sitemap data
3182 - * (`jp_sitemap*` posts), the `jetpack-sitemap-state` option, sitemap settings, or the
3183 - * `jp_sitemap_cron_hook` cron, so no regeneration is triggered. `add_option()` only
3184 - * seeds when the option is absent, so it is safe to run on every version bump and
3185 - * never reverts a value the user has since set.
3186 - *
3187 - * Hooked on `updating_jetpack_version`; the version arguments are not needed because
3188 - * `add_option()` provides the run-once guard.
3189 - */
3190 - public static function migrate_sitemaps_module_to_seo_option() {
3191 - // Ignore wpcomsh's temporary private-site suppression while preserving permanent
3192 - // module overrides. {@see self::is_module_active_for_seo_option()}.
3193 - $sitemaps_active = self::is_module_active_for_seo_option( 'sitemaps' );
3194 -
3195 - add_option( Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION, $sitemaps_active );
3196 - }
3197 -
3198 - /**
3199 - * Keeps the Jetpack SEO sitemap option in sync with the legacy `sitemaps` module
3200 - * while both still exist.
3201 - *
3202 - * Hooked to the module's activate/deactivate actions, so toggling sitemaps from any
3203 - * surface (the legacy Traffic settings, the SEO Settings tab, or WP-CLI) keeps the
3204 - * durable {@see Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION} option current. The
3205 - * actions fire after `active_modules` is updated, so the configured state already
3206 - * reflects the new choice. Ignore temporary private-site suppression without bypassing
3207 - * permanent module overrides. Removed alongside the module itself.
3208 - */
3209 - public static function sync_seo_sitemap_option() {
3210 - update_option( Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION, self::is_module_active_for_seo_option( 'sitemaps' ) );
3211 - }
3212 -
3213 - /**
3214 - * Records whether the standalone Canonical URLs module is active so the setting survives
3215 - * the module's removal.
3216 - *
3217 - * The Jetpack SEO product reads the {@see Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION}
3218 - * option instead of the `canonical-urls` module's active state. Module-active state is
3219 - * filtered against the modules present on disk, so once the standalone module is
3220 - * removed it would read as inactive even for sites that had it on. This one-time
3221 - * migration captures the configured module state — which persists regardless of
3222 - * whether the module file is present — into the durable option.
3223 - *
3224 - * Deliberately non-destructive: `add_option()` only seeds when the option is absent, so
3225 - * it is safe to run on every version bump and never reverts a value the user has since
3226 - * set.
3227 - *
3228 - * Hooked on `updating_jetpack_version`; the version arguments are not needed because
3229 - * `add_option()` provides the run-once guard.
3230 - */
3231 - public static function migrate_canonical_urls_module_to_seo_option() {
3232 - $canonical_active = self::is_module_active_for_seo_option( 'canonical-urls' );
3233 -
3234 - add_option( Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION, $canonical_active );
3235 - }
3236 -
3237 - /**
3238 - * Keeps the Jetpack SEO canonical-urls option in sync with the legacy `canonical-urls`
3239 - * module while both still exist.
3240 - *
3241 - * Hooked to the module's activate/deactivate actions, so toggling canonical URLs from any
3242 - * surface (the legacy Traffic settings, the SEO Settings tab, or WP-CLI) keeps the
3243 - * durable {@see Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION} option current. The
3244 - * actions fire after `active_modules` is updated, so the configured state already
3245 - * reflects the new choice. Permanent module overrides remain authoritative. Removed
3246 - * alongside the module itself.
3247 - */
3248 - public static function sync_seo_canonical_urls_option() {
3249 - update_option( Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION, self::is_module_active_for_seo_option( 'canonical-urls' ) );
3250 - }
3251 -
3252 - /**
3253 - * Repairs durable SEO module-state options that the first pass of the migration seeded
3254 - * from a filtered read.
3255 - *
3256 - * Jetpack 16.0 seeded {@see Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION} and
3257 - * {@see Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION} through
3258 - * {@see Modules::is_active()}, which passes the `jetpack_active_modules` filter. A site
3259 - * that was private at the time therefore recorded `sitemaps` as off even though the user
3260 - * had it on, and because the migration seeds with `add_option()` the value was never
3261 - * revisited — making the site public again did not restore the setting.
3262 - *
3263 - * This runs once and rewrites both options from the site's configured module state,
3264 - * including permanent module overrides. That is safe against a choice the user has made
3265 - * since: every surface that toggles these settings (the legacy Traffic page, the SEO
3266 - * Settings tab, WP-CLI) goes through {@see Modules::activate()}/{@see Modules::deactivate()},
3267 - * so the module state and durable option are already in agreement wherever the original
3268 - * migration got it right.
3269 - *
3270 - * Idempotent: the marker is written with `add_option()`, so reruns on later version bumps
3271 - * are no-ops. Like the migrations it seeds from, it touches no sitemap data or cron state.
3272 - *
3273 - * @since 16.1
3274 - */
3275 - public static function reconcile_seo_module_state_options() {
3276 - if ( get_option( self::SEO_MODULE_STATE_RECONCILED_OPTION ) ) {
3277 - return;
3278 - }
3279 -
3280 - update_option( Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION, self::is_module_active_for_seo_option( 'sitemaps' ) );
3281 - update_option( Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION, self::is_module_active_for_seo_option( 'canonical-urls' ) );
3282 -
3283 - add_option( self::SEO_MODULE_STATE_RECONCILED_OPTION, true );
3284 - }
3285 -
3286 - /**
3287 - * Wires up the migration + sync hooks that keep the durable Jetpack SEO module-state
3288 - * options ({@see Jetpack_SEO_Initializer::SITEMAP_ENABLED_OPTION} /
3289 - * {@see Jetpack_SEO_Initializer::CANONICAL_ENABLED_OPTION}) seeded and in sync with their
3290 - * legacy modules. Called once from `load-jetpack.php`.
3291 - *
3292 - * Extracted from file scope so the wiring is unit-testable (file-scope `add_action()`
3293 - * calls run during bootstrap and can't be exercised by a test). Removed alongside the
3294 - * modules in the deferred post-convergence follow-up that absorbs them into Jetpack SEO.
3295 - */
3296 - public static function register_seo_module_migration_hooks() {
3297 - add_action( 'updating_jetpack_version', array( 'Jetpack', 'migrate_sitemaps_module_to_seo_option' ) );
3298 - add_action( 'jetpack_activate_module_sitemaps', array( 'Jetpack', 'sync_seo_sitemap_option' ) );
3299 - add_action( 'jetpack_deactivate_module_sitemaps', array( 'Jetpack', 'sync_seo_sitemap_option' ) );
3300 -
3301 - add_action( 'updating_jetpack_version', array( 'Jetpack', 'migrate_canonical_urls_module_to_seo_option' ) );
3302 - add_action( 'jetpack_activate_module_canonical-urls', array( 'Jetpack', 'sync_seo_canonical_urls_option' ) );
3303 - add_action( 'jetpack_deactivate_module_canonical-urls', array( 'Jetpack', 'sync_seo_canonical_urls_option' ) );
3304 -
3305 - // Runs after both migrations above (default priority, registered last) so a freshly
3306 - // seeded site is already correct and the reconciliation is a no-op there.
3307 - add_action( 'updating_jetpack_version', array( 'Jetpack', 'reconcile_seo_module_state_options' ) );
3308 - }
3309 -
3310 - /**
3311 3125 * Seeds the Jetpack SEO discoverability cohort once, so the new SEO surface is
3312 3126 * auto-discoverable on fresh installs but opt-in on existing ones (JETPACK-1700).
3313 3127 *
3314 3128 * Hooked on `updating_jetpack_version`, which fires on every install including the
@@ -4140,9 +3954,9 @@
4140 3954 */
4141 3955 public function plugin_action_links( $actions ) {
4142 3956 if ( current_user_can( 'jetpack_manage_modules' ) && ( self::is_connection_ready() || ( new Status() )->is_offline_mode() ) ) {
4143 3957 return array_merge(
4144 - array( 'settings' => sprintf( '<a href="%s">%s</a>', esc_url( self::admin_url( 'page=jetpack#/settings' ) ), __( 'Settings', 'jetpack' ) ) ),
3958 + array( 'settings' => sprintf( '<a href="%s">%s</a>', esc_url( self::admin_url( 'page=jetpack-settings#/settings' ) ), __( 'Settings', 'jetpack' ) ) ),
4145 3959 $actions
4146 3960 );
4147 3961 }
4148 3962
@@ -4178,9 +3992,9 @@
4178 3992 Assets::enqueue_script( 'jetpack-plugins-page-js' );
4179 3993
4180 3994 // Add objects to be passed to the initial state of the app.
4181 3995 // Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280.
4182 - wp_add_inline_script( 'jetpack-plugins-page-js', 'var Initial_State=' . wp_json_encode( Jetpack_Redux_State_Helper::get_minimal_state(), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';', 'before' );
3996 + wp_add_inline_script( 'jetpack-plugins-page-js', 'var Initial_State=' . wp_json_encode( Jetpack_Redux_State_Helper::get_plugins_page_state(), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';', 'before' );
4183 3997
4184 3998 add_action( 'admin_footer', array( $this, 'jetpack_plugin_portal_containers' ) );
4185 3999 }
4186 4000 }