PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-beta 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 All 507 releases
jetpack / jetpack_vendor / automattic / jetpack-seo / src / class-surface-visibility.php

class-surface-visibility.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.7, at jetpack_vendor/automattic/jetpack-seo/src/class-surface-visibility.php

128 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The discoverability cohort for the Jetpack SEO surface, and the opt-in
4 * that flips it: whether the admin menu registers on this site, and the
5 * REST route existing self-hosted installs use to switch over.
6 *
7 * @package automattic/jetpack-seo-package
8 */
9
10 namespace Automattic\Jetpack\SEO;
11
12 use Automattic\Jetpack\Modules;
13 use Automattic\Jetpack\Status\Host;
14
15 /**
16 * Decides whether the SEO surface is discoverable and handles the opt-in.
17 */
18 class Surface_Visibility {
19
20 /**
21 * Whether the Jetpack SEO surface should be discoverable (admin menu registered).
22 *
23 * WordPress.com sites (Simple + Atomic) are always discoverable — how SEO presents
24 * there is a Dotcom decision, independent of the self-hosted rollout. On self-hosted
25 * sites the durable {@see Initializer::VISIBILITY_OPTION} cohort flag decides: fresh installs
26 * are seeded visible, existing installs stay hidden until they opt in. Defaults to
27 * hidden when the option is absent (e.g. before the plugin's seed has run), so an
28 * existing site is never surprised by the new surface before its cohort is recorded.
29 *
30 * @return bool
31 */
32 public static function is_visible() {
33 if ( class_exists( 'Automattic\\Jetpack\\Status\\Host' ) && ( new Host() )->is_wpcom_platform() ) {
34 return true;
35 }
36
37 return (bool) get_option( Initializer::VISIBILITY_OPTION, false );
38 }
39
40 /**
41 * Whether to offer an existing install the chance to opt into the new SEO experience.
42 *
43 * The single source of truth for the opt-in surfaces (legacy Traffic-page banner, My
44 * Jetpack card). True only when the SEO product is available and the surface isn't
45 * visible yet — and since {@see self::is_visible()} already returns true for
46 * WordPress.com and for self-hosted installs that have opted in, "not visible"
47 * cleanly means "a self-hosted install that hasn't opted in".
48 *
49 * @return bool
50 */
51 public static function is_optin_available() {
52 return Initializer::is_available() && ! self::is_visible();
53 }
54
55 /**
56 * Expose whether this install should be offered the SEO opt-in, onto
57 * `window.JetpackScriptData.seo.optin_available` for other admin surfaces (e.g. the
58 * legacy Traffic-page banner). Only hooked when the feature flag is on, so the field is
59 * simply absent otherwise.
60 *
61 * @param array $data Script data being injected onto the page.
62 * @return array
63 */
64 public static function inject_optin_availability( $data ) {
65 if ( ! is_array( $data ) ) {
66 $data = array();
67 }
68
69 $data[ Initializer::SCRIPT_DATA_KEY ]['optin_available'] = self::is_optin_available();
70 // Read by the legacy Traffic page to hide its SEO / Sitemaps sections once the
71 // site is on the new experience (fresh install / opted-in / WordPress.com), so the
72 // two surfaces never show at once. The legacy sections stay for self-hosted installs
73 // that haven't opted in.
74 $data[ Initializer::SCRIPT_DATA_KEY ]['surface_visible'] = self::is_visible();
75
76 return $data;
77 }
78
79 /**
80 * Register the opt-in REST route that switches an existing self-hosted install over to
81 * the new SEO experience.
82 *
83 * Lives on the `jetpack/v4` namespace and is registered ahead of the cohort gate, so a
84 * site whose SEO surface is still hidden can reach it from the legacy Traffic page or
85 * My Jetpack. See {@see self::handle_optin()}.
86 *
87 * @return void
88 */
89 public static function register_optin_route() {
90 register_rest_route(
91 'jetpack/v4',
92 '/seo/opt-in',
93 array(
94 'methods' => \WP_REST_Server::CREATABLE,
95 'callback' => array( __CLASS__, 'handle_optin' ),
96 'permission_callback' => function () {
97 return current_user_can( 'manage_options' );
98 },
99 )
100 );
101 }
102
103 /**
104 * Opt an existing install into the new SEO experience: mark the surface visible and
105 * activate the `seo-tools` module, then hand back the dashboard URL to redirect to.
106 *
107 * Idempotent — re-opting-in is harmless. `Modules::activate()` is called with
108 * `$exit = false, $redirect = false`; the defaults would `exit()` and send a 302,
109 * which break a REST response.
110 *
111 * @return \WP_REST_Response
112 */
113 public static function handle_optin() {
114 update_option( Initializer::VISIBILITY_OPTION, true );
115
116 if ( class_exists( 'Automattic\\Jetpack\\Modules' ) ) {
117 ( new Modules() )->activate( 'seo-tools', false, false );
118 }
119
120 return rest_ensure_response(
121 array(
122 'success' => true,
123 'redirect' => admin_url( 'admin.php?page=' . Admin_Page::MENU_SLUG ),
124 )
125 );
126 }
127 }
128