Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Request
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
2 / 2
18
100.00% covered (success)
100.00%
1 / 1
 is_frontend
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
14
 get_vary_headers
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Get information about the current request.
4 *
5 * @package automattic/jetpack-status
6 */
7
8namespace Automattic\Jetpack\Status;
9
10use Automattic\Jetpack\Constants;
11
12/**
13 * Get information about the current request.
14 */
15class Request {
16    /**
17     * Determine whether the current request is for accessing the frontend.
18     * Also update Vary headers to indicate that the response may vary by Accept header.
19     *
20     * @since 6.0.3 Added $send_vary_headers argument.
21     *
22     * @param bool $send_vary_headers Whether to send Vary headers.
23     *
24     * @return bool True if it's a frontend request, false otherwise.
25     */
26    public static function is_frontend( $send_vary_headers = true ) {
27        $is_frontend        = true;
28        $is_varying_request = true;
29
30        if (
31            is_admin()
32            || wp_doing_ajax()
33            || wp_is_jsonp_request()
34            || is_feed()
35            || Constants::is_true( 'REST_REQUEST' )
36            || Constants::is_true( 'REST_API_REQUEST' )
37            || Constants::is_true( 'WP_CLI' )
38            || Constants::is_true( 'WPCOM_CLI_SCRIPT' ) // Special case for CLI scripts on WP.com that aren't using WP CLI.
39        ) {
40            $is_frontend        = false;
41            $is_varying_request = false;
42        } elseif (
43            wp_is_json_request()
44            || wp_is_xml_request()
45        ) {
46            $is_frontend = false;
47        }
48
49        /*
50        * Check existing headers for the request.
51        * If there is no existing Vary Accept header, add one.
52        */
53        if ( $send_vary_headers && $is_varying_request && ! headers_sent() ) {
54            $headers           = headers_list();
55            $vary_header_parts = self::get_vary_headers( $headers );
56
57            header( 'Vary: ' . implode( ', ', $vary_header_parts ) );
58        }
59
60        /**
61         * Filter whether the current request is for accessing the frontend.
62         *
63         * @since jetpack-9.0.0
64         * @since 6.0.3 Added $send_vary_headers argument.
65         *
66         * @param bool $is_frontend Whether the current request is for accessing the frontend.
67         * @param bool $send_vary_headers Whether to send Vary headers.
68         */
69        return (bool) apply_filters( 'jetpack_is_frontend', $is_frontend, $send_vary_headers );
70    }
71
72    /**
73     * Go through headers and get a list of Vary headers to add,
74     * including Vary on Accept and Content-Type if necessary.
75     *
76     * @since jetpack-12.2
77     *
78     * @param array $headers The headers to be sent.
79     *
80     * @return array $vary_header_parts Vary Headers to be sent.
81     */
82    public static function get_vary_headers( $headers = array() ) {
83        $vary_header_parts = array( 'accept', 'content-type' );
84
85        foreach ( $headers as $header ) {
86            // Check for a Vary header.
87            if ( ! str_starts_with( strtolower( $header ), 'vary:' ) ) {
88                continue;
89            }
90
91            // If the header is a wildcard, we'll return that.
92            if ( str_contains( $header, '*' ) ) {
93                $vary_header_parts = array( '*' );
94                break;
95            }
96
97            // Remove the Vary: part of the header.
98            $header = preg_replace( '/^vary\:\s?/i', '', $header );
99
100            // Remove spaces from the header.
101            $header = str_replace( ' ', '', $header );
102
103            // Break the header into parts.
104            $header_parts = explode( ',', strtolower( $header ) );
105
106            // Build an array with the Accept header and what was already there.
107            $vary_header_parts = array_values( array_unique( array_merge( $vary_header_parts, $header_parts ) ) );
108        }
109
110        return $vary_header_parts;
111    }
112}