Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 85
0.00% covered (danger)
0.00%
0 / 7
CRAP
n/a
0 / 0
wpcomsh_maybe_disable_fse
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wpcomsh_coming_soon_get_atomic_persistent_data
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
wpcomsh_public_preview_links_get_atomic_persistent_data
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
wpcom_public_coming_soon_replace_yoast_seo_notice
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
182
wpcom_fse_spt_add_tracking_identity_to_config
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
wpcom_fse_global_editors_script
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
logstash_log_global_styles
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * Customizations for the Full Site Editing plugin.
4 *
5 * @package wpcomsh
6 */
7
8/**
9 * Disables Full Site Editing if the eligability option does not exist.
10 *
11 * @return bool true if FSE should be disabled, false if FSE should be enabled
12 */
13function wpcomsh_maybe_disable_fse() {
14    // Always disable FSE if the site is not eligible.
15    return ! get_option( 'a8c-fse-is-eligible' );
16}
17add_filter( 'a8c_disable_full_site_editing', 'wpcomsh_maybe_disable_fse' );
18
19// Enable block patterns API.
20add_filter( 'a8c_enable_block_patterns_api', '__return_true' );
21
22/**
23 * Enable coming soon for all sites.
24 */
25add_filter( 'a8c_enable_public_coming_soon', '__return_true' );
26
27/**
28 * Returns Atomic persistent data value for wpcom_public_coming_soon.
29 *
30 * @param string $wpcom_public_coming_soon Value for the coming soon option.
31 *
32 * @return string The value of WPCOM_PUBLIC_COMING_SOON if set, otherwise the option value.
33 */
34function wpcomsh_coming_soon_get_atomic_persistent_data( $wpcom_public_coming_soon ) {
35    $persistent_data                   = new Atomic_Persistent_Data();
36    $persistent_data_coming_soon_value = $persistent_data->WPCOM_PUBLIC_COMING_SOON; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
37
38    if ( $persistent_data_coming_soon_value !== null ) {
39        return $persistent_data_coming_soon_value;
40    }
41
42    return $wpcom_public_coming_soon;
43}
44add_filter( 'option_wpcom_public_coming_soon', 'wpcomsh_coming_soon_get_atomic_persistent_data' );
45
46/**
47 * Returns Atomic persistent data value for wpcom_public_preview_links.
48 *
49 * @param string $wpcom_public_preview_links Value for the preview links option.
50 *
51 * @return string The value of WPCOM_PUBLIC_PREVIEW_LINKS if set, otherwise the option value.
52 */
53function wpcomsh_public_preview_links_get_atomic_persistent_data( $wpcom_public_preview_links ) {
54    $persistent_data                            = new Atomic_Persistent_Data();
55    $persistent_data_public_preview_links_value = $persistent_data->WPCOM_PUBLIC_PREVIEW_LINKS; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
56
57    if ( $persistent_data_public_preview_links_value !== null ) {
58        return json_decode( $persistent_data_public_preview_links_value );
59    }
60
61    return $wpcom_public_preview_links;
62}
63// need to hook to default_option_* too because if this option doesn't exist, the hook wouldn't run.
64add_filter( 'default_option_wpcom_public_preview_links', 'wpcomsh_public_preview_links_get_atomic_persistent_data' );
65add_filter( 'option_wpcom_public_preview_links', 'wpcomsh_public_preview_links_get_atomic_persistent_data' );
66
67/**
68 * Replaces the Yoast SEO error notice from that warns of SEO issues
69 * when the site is in Coming Soon mode,
70 * or when search engines are discouraged from indexing the site.
71 *
72 * @return void
73 */
74function wpcom_public_coming_soon_replace_yoast_seo_notice() {
75    $wpseo_options = get_option( 'wpseo', false );
76    if ( ! $wpseo_options ) {
77        // Do nothing if Yoast is not installed.
78        return;
79    }
80
81    $is_wpcom_public_coming_soon_enabled = 1 === (int) get_option( 'wpcom_public_coming_soon', 0 );
82    $are_search_engines_discouraged      = 0 === (int) get_option( 'blog_public' );
83
84    /*
85     * The Yoast SEO notice should be replaced either if the site is in Coming Soon mode or
86     * if indexing is discouraged, on the site.
87     */
88    $should_replace_yoast_notice = $are_search_engines_discouraged || $is_wpcom_public_coming_soon_enabled;
89
90    if ( $should_replace_yoast_notice && empty( $wpseo_options['ignore_search_engines_discouraged_notice'] ) ) {
91        // Hide the Yoast SEO notice if it's not hidden and the site is set to Coming Soon mode.
92        $wpseo_options['ignore_search_engines_discouraged_notice'] = true;
93        update_option( 'wpseo', $wpseo_options );
94    }
95
96    if ( ! $should_replace_yoast_notice && ! empty( $wpseo_options['ignore_search_engines_discouraged_notice'] ) ) {
97        // Restore the default setting if Coming Soon mode is disabled.
98        $wpseo_options['ignore_search_engines_discouraged_notice'] = false;
99        update_option( 'wpseo', $wpseo_options );
100    }
101
102    $pagenow             = $GLOBALS['pagenow'];
103    $on_wpseo_admin_page = $pagenow === 'admin.php' && strpos( filter_input( INPUT_GET, 'page' ), 'wpseo' ) === 0;
104    $notice_pages        = array(
105        'index.php',
106        'plugins.php',
107        'update-core.php',
108    );
109
110    // Only show the notice on certain admin pages and Yoast SEO admin pages.
111    if (
112        $should_replace_yoast_notice
113        && ! empty( $wpseo_options['ignore_search_engines_discouraged_notice'] )
114        && ( $on_wpseo_admin_page || in_array( $pagenow, $notice_pages, true ) )
115    ) {
116        // Get site slug & settings url.
117        $blog_id      = get_current_blog_id();
118        $site_url     = get_home_url( $blog_id );
119        $site_slug    = wp_parse_url( $site_url, PHP_URL_HOST );
120        $settings_url = 'https://wordpress.com/sites/settings/v2/' . $site_slug . '/site-visibility';
121
122        if ( $is_wpcom_public_coming_soon_enabled ) {
123            /* translators: 1: opening anchor tag; 2: closing anchor tag. */
124            $text = __( 'Heads up! Your site is currently in Coming Soon mode. If you want search engines to show this site in their search results you have to launch your site. %1$sClick here%2$s to change your site\'s privacy settings.', 'wpcomsh' );
125        } else {
126            /* translators: 1: opening anchor tag; 2: closing anchor tag. */
127            $text = __( 'Heads up! Search engines are currently discouraged from indexing your site. If you want search engines to show this site in their search results you have to launch your site. %1$sClick here%2$s to change your site\'s privacy settings.', 'wpcomsh' );
128        }
129
130        printf(
131            '<div class="notice notice-info is-dismissible"><p><strong>' . esc_html( $text ) . '</strong></p></div>',
132            '<a href="' . esc_url( $settings_url ) . '">',
133            '</a>'
134        );
135    }
136}
137add_action( 'admin_notices', 'wpcom_public_coming_soon_replace_yoast_seo_notice' );
138
139/**
140 * Adds the tracking identity to config that is passed to Starter Page Template frontend.
141 * That way we can publish our code to plugin directory sans tracking code.
142 *
143 * @param  array $config Config for the frontend.
144 * @return array The modified config.
145 */
146function wpcom_fse_spt_add_tracking_identity_to_config( $config ) {
147    // Load identity.
148    $has_active_jetpack = ( class_exists( 'Jetpack' ) && Jetpack::is_connection_ready() );
149    if ( $has_active_jetpack && class_exists( 'Jetpack_Tracks_Client' ) ) {
150        $config['tracksUserData'] = Jetpack_Tracks_Client::get_connected_user_tracks_identity();
151        // Enqueue tracks script.
152        wp_enqueue_script(
153            'jp-tracks',
154            '//stats.wp.com/w.js',
155            array(),
156            gmdate( 'YW' ),
157            true
158        );
159    }
160
161    return $config;
162}
163add_filter( 'fse_starter_page_templates_config', 'wpcom_fse_spt_add_tracking_identity_to_config' );
164
165/**
166 * Adds site meta data for Gutenberg Tracking.
167 *
168 * @see https://github.com/Automattic/wp-calypso/pull/34655
169 */
170function wpcom_fse_global_editors_script() {
171    if ( ! class_exists( 'Jetpack' ) || ! class_exists( 'Jetpack_Options' ) || ! Jetpack::is_connection_ready() ) {
172        return;
173    }
174
175    $script = sprintf( 'var _currentSiteId=%d,_currentSiteType="atomic";', (int) Jetpack_Options::get_option( 'id' ) );
176
177    wp_add_inline_script( 'editor', $script, 'before' );
178    wp_add_inline_script( 'wp-list-reusable-blocks', $script );
179}
180add_action( 'admin_enqueue_scripts', 'wpcom_fse_global_editors_script' );
181
182/**
183 * This function hooks into the action that is dispatched when changes to the Global Styles of site are made.
184 *
185 * @param string $message The message that will be logged.
186 *
187 * @return void
188 */
189function logstash_log_global_styles( $message ) {
190    // We sample the logs so that we only send 1 in 100 logs. We don't treat proxied requests in any special way.
191    if ( time() % 100 !== 0 ) {
192        return;
193    }
194
195    // This data has the format that's expected by the logstash endpoint.
196    $data = wp_json_encode(
197        array(
198            'feature' => 'atomic_global_styles_gate',
199            'message' => $message,
200            'extra'   => array(
201                'trace'          => ( new Exception() )->getTraceAsString(),
202                'atomic_site_id' => wpcomsh_get_atomic_site_id(),
203            ),
204        ),
205        JSON_UNESCAPED_SLASHES
206    );
207
208    // We FAF the call to the logging endpoint.
209    wp_remote_post( 'https://public-api.wordpress.com/rest/v1.1/logstash', array( 'body' => array( 'params' => $data ) ) );
210}
211add_action( 'global_styles_log', 'logstash_log_global_styles' );