Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
77.14% covered (warning)
77.14%
27 / 35
50.00% covered (danger)
50.00%
1 / 2
CRAP
n/a
0 / 0
Automattic\Jetpack\Jetpack_Mu_Wpcom\Blog_Privacy\robots_txt
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
9
Automattic\Jetpack\Jetpack_Mu_Wpcom\Blog_Privacy\remove_og_tags
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Blog Privacy Settings
4 *
5 * Controls for Blog Privacy are spread out over several different places.
6 * * WordPress Core (all sites: `blog_privacy_selector`, `blog_public`)
7 * * wpcomsh (WoA: Private Site feature)
8 * * WP.com (simple: `blog_public`)
9 * * This jetpack-mu-wpcom feature (WoA, simple: `wpcom_data_sharing_opt_out` robots.txt user agent blocks)
10 *
11 * @package automattic/jetpack-mu-wpcom
12 */
13
14declare( strict_types = 1 );
15
16namespace Automattic\Jetpack\Jetpack_Mu_Wpcom\Blog_Privacy;
17
18/**
19 * Filters the robots.txt contents based on the value of the wpcom_data_sharing_opt_out option.
20 *
21 * @param string $output The contents of robots.txt.
22 * @param bool   $public Whether the site is considered public.
23 * @return string
24 */
25function robots_txt( $output, $public ): string {
26    if ( ! is_string( $output ) ) {
27        $output = '';
28    }
29
30    // WordPress passes in a bool. Re-fetch as an int to handle our custom "-1" value.
31    $public = (int) get_option( 'blog_public' );
32
33    // If the site is completely private, don't bother with the additional restrictions.
34    // For blog_public=0, WP.com Disallows all user agents and Core does not (relying on <meta name="robots">).
35    // Let wpcom do it's thing to not clutter the robots.txt file.
36    if ( -1 === $public || ( 0 === $public && defined( 'IS_WPCOM' ) && IS_WPCOM ) ) {
37        return $output;
38    }
39
40    // An option oddly named because of history.
41    if ( 0 === $public || get_option( 'wpcom_data_sharing_opt_out' ) ) {
42        $ai_bots = array(
43            'Amazonbot',
44            'anthropic-ai',
45            'Applebot-Extended',
46            'Bytespider',
47            'CCBot',
48            'ClaudeBot',
49            'FacebookBot',
50            'Google-Extended',
51            'GPTBot',
52            'meta-externalagent',
53            'omgili',
54            'omgilibot',
55            'PerplexityBot',
56            'SentiBot',
57            'sentibot',
58        );
59
60        foreach ( $ai_bots as $ai_bot ) {
61            $output .= "\nUser-agent: {$ai_bot}\n";
62            $output .= "Disallow: /\n";
63        }
64    }
65
66    return $output;
67}
68
69add_filter( 'robots_txt', __NAMESPACE__ . '\\robots_txt', 12, 2 );
70
71/**
72 * Disable the Open Graph Tags based on the value of either wpcom_public_coming_soon option.
73 */
74function remove_og_tags() {
75    if ( ! (bool) get_option( 'wpcom_public_coming_soon' ) ) {
76        return;
77    }
78
79    // Disable Jetpack Open Graph Tags.
80    add_filter( 'jetpack_enable_open_graph', '__return_false', 99 );
81
82    // Disable Yoast SEO. See https://developer.yoast.com/customization/yoast-seo/disabling-yoast-seo/.
83    if ( function_exists( 'YoastSEO' ) && class_exists( 'Yoast\WP\SEO\Integrations\Front_End_Integration', false ) ) {
84        // @phan-suppress-next-line PhanUndeclaredFunction, PhanUndeclaredClassReference
85        $front_end = \YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Front_End_Integration::class );
86        remove_action( 'wpseo_head', array( $front_end, 'present_head' ), -9999 );
87    }
88}
89
90add_action( 'wp_head', __NAMESPACE__ . '\remove_og_tags', 0 );