Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CookieState
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 2
600
0.00% covered (danger)
0.00%
0 / 1
 state
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
420
 should_set_cookie
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * Pass state to subsequent requests via cookies.
4 *
5 * @package automattic/jetpack-status
6 */
7
8namespace Automattic\Jetpack;
9
10/**
11 * Class Automattic\Jetpack\Status
12 *
13 * Used to retrieve information about the current status of Jetpack and the site overall.
14 */
15class CookieState {
16
17    /**
18     * State is passed via cookies from one request to the next, but never to subsequent requests.
19     * SET: state( $key, $value );
20     * GET: $value = state( $key );
21     *
22     * @param string $key State key.
23     * @param string $value Value.
24     * @param bool   $restate Reset the cookie (private).
25     */
26    public function state( $key = null, $value = null, $restate = false ) {
27        static $state = array();
28        static $path, $domain; // this initializes values to null
29        if ( ! isset( $path ) ) {
30            require_once ABSPATH . 'wp-admin/includes/plugin.php';
31            $admin_url = ( new Paths() )->admin_url();
32            $bits      = wp_parse_url( $admin_url );
33
34            if ( is_array( $bits ) ) {
35                $path   = ( isset( $bits['path'] ) ) ? dirname( $bits['path'] ) : null;
36                $domain = ( isset( $bits['host'] ) ) ? $bits['host'] : null;
37            }
38        }
39
40        // Extract state from cookies and delete cookies.
41        if ( isset( $_COOKIE['jetpackState'] ) && is_array( $_COOKIE['jetpackState'] ) ) {
42            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- User should sanitize if necessary.
43            $yum = wp_unslash( $_COOKIE['jetpackState'] );
44            unset( $_COOKIE['jetpackState'] );
45            foreach ( $yum as $k => $v ) {
46                if ( strlen( $v ) ) {
47                    $state[ $k ] = $v;
48                }
49                // @phan-suppress-next-line PhanTypeMismatchArgumentInternal -- Setting cookie to false is valid and documented for deletion.
50                setcookie( "jetpackState[$k]", false, 0, $path, $domain, is_ssl(), true );
51            }
52        }
53
54        if ( $restate ) {
55            foreach ( $state as $k => $v ) {
56                setcookie( "jetpackState[$k]", $v, 0, $path, $domain, is_ssl(), true );
57            }
58            return;
59        }
60
61        // Get a state variable.
62        if ( isset( $key ) && ! isset( $value ) ) {
63            if ( array_key_exists( $key, $state ) ) {
64                return $state[ $key ];
65            }
66            return null;
67        }
68
69        // Set a state variable.
70        if ( isset( $key ) && isset( $value ) ) {
71            if ( is_array( $value ) && isset( $value[0] ) ) {
72                $value = $value[0];
73            }
74            $state[ $key ] = $value;
75            if ( ! headers_sent() ) {
76                if ( $this->should_set_cookie( $key ) ) {
77                    setcookie( "jetpackState[$key]", $value, 0, $path, $domain, is_ssl(), true );
78                }
79            }
80        }
81    }
82
83    /**
84     * Determines whether the jetpackState[$key] value should be added to the
85     * cookie.
86     *
87     * @param string $key The state key.
88     *
89     * @return boolean Whether the value should be added to the cookie.
90     */
91    public function should_set_cookie( $key ) {
92        global $current_screen;
93        $page = isset( $current_screen->base ) ? $current_screen->base : null;
94
95        if ( 'toplevel_page_jetpack' === $page && 'display_update_modal' === $key ) {
96            return false;
97        }
98
99        return true;
100    }
101}