Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.38% covered (warning)
84.38%
27 / 32
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Initial_State
84.38% covered (warning)
84.38%
27 / 32
50.00% covered (danger)
50.00%
2 / 4
8.24
0.00% covered (danger)
0.00%
0 / 1
 get_data
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
4
 set_connection_script_data
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 render
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 render_script
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * The React initial state.
4 *
5 * @package automattic/jetpack-connection
6 */
7
8namespace Automattic\Jetpack\Connection;
9
10use Automattic\Jetpack\Status;
11
12/**
13 * The React initial state.
14 */
15class Initial_State {
16
17    /**
18     * Get the initial state data.
19     *
20     * @return array
21     */
22    private static function get_data() {
23        global $wp_version;
24
25        $status = new Status();
26
27        // Only expose the owner's identity to users who can act on connection issues:
28        // this state is printed for any logged-in user loading connection scripts
29        // (e.g. contributors in the editor). The owner is derived from the master_user
30        // option rather than the token-dependent Manager::get_connection_owner(): that
31        // method returns false exactly when the owner's token is broken, which is the
32        // scenario connection-error UIs need this data for (and it re-reports
33        // invalid_connection_owner as a side effect). Unlike
34        // userConnectionData.connectionOwner (the *connected* owner), this field
35        // identifies who holds ownership regardless of token health.
36        $connection_owner = null;
37        if ( current_user_can( 'jetpack_connect' ) ) {
38            $owner_id = (int) \Jetpack_Options::get_option( 'master_user' );
39            $owner    = $owner_id > 0 ? get_userdata( $owner_id ) : false;
40
41            if ( $owner instanceof \WP_User ) {
42                $connection_owner = array(
43                    'id'          => $owner_id,
44                    'displayName' => $owner->display_name,
45                );
46            }
47        }
48
49        return array(
50            'apiRoot'                 => esc_url_raw( rest_url() ),
51            'apiNonce'                => wp_create_nonce( 'wp_rest' ),
52            'registrationNonce'       => wp_create_nonce( 'jetpack-registration-nonce' ),
53            'connectionStatus'        => REST_Connector::connection_status( false ),
54            'userConnectionData'      => REST_Connector::get_user_connection_data( false ),
55            'connectedPlugins'        => REST_Connector::get_connection_plugins( false ),
56            'wpVersion'               => $wp_version,
57            'siteSuffix'              => $status->get_site_suffix(),
58            'connectionErrors'        => Error_Handler::get_instance()->get_displayable_errors(),
59            'isOfflineMode'           => $status->is_offline_mode(),
60            'calypsoEnv'              => ( new Status\Host() )->get_calypso_env(),
61            'isOwnershipTransferable' => ( new Manager() )->is_ownership_transferable(),
62            'connectionOwner'         => $connection_owner,
63        );
64    }
65
66    /**
67     * Set the connection script data.
68     *
69     * @param array $data The script data.
70     */
71    public static function set_connection_script_data( $data ) {
72
73        $data['connection'] = self::get_data();
74
75        if ( empty( $data['site']['wpcom']['blog_id'] ) ) {
76            $data['site']['wpcom']['blog_id'] = absint( \Jetpack_Options::get_option( 'id', 0 ) );
77        }
78
79        return $data;
80    }
81
82    /**
83     * Render the initial state into a JavaScript variable.
84     *
85     * @return string
86     */
87    public static function render() {
88        /*
89         * `window.jpTracksContext` is an intentionally minimal, Tracks-specific global used by the
90         * @automattic/jetpack-analytics package to read `blog_id` at event-fire time. It exists
91         * separately from `window.JetpackScriptData` because the analytics package is consumed in
92         * contexts (e.g. Boost frontend) where `JetpackScriptData` is not reliably available, and
93         * coupling the analytics package to that schema would widen its surface unnecessarily.
94         * When both are present, `JetpackScriptData.site.wpcom.blog_id` is populated via
95         * `set_connection_script_data()` above for other consumers.
96         */
97        return 'var JP_CONNECTION_INITIAL_STATE; typeof JP_CONNECTION_INITIAL_STATE === "object" || (JP_CONNECTION_INITIAL_STATE = ' . wp_json_encode( self::get_data(), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ');'
98            . sprintf( 'window.jpTracksContext = window.jpTracksContext || {}; window.jpTracksContext.blog_id = %s;', absint( \Jetpack_Options::get_option( 'id', 0 ) ) );
99    }
100
101    /**
102     * Render the initial state using an inline script.
103     *
104     * @param string $handle The JS script handle.
105     *
106     * @return void
107     */
108    public static function render_script( $handle ) {
109        wp_add_inline_script( $handle, static::render(), 'before' );
110    }
111}