Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.51% covered (warning)
88.51%
77 / 87
50.00% covered (danger)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
WPCOM_REST_API_V3_Endpoint_JITM
91.67% covered (success)
91.67%
77 / 84
50.00% covered (danger)
50.00%
3 / 6
18.19
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
1 / 1
1
 get_item
78.57% covered (warning)
78.57%
11 / 14
0.00% covered (danger)
0.00%
0 / 1
6.35
 get_item_permissions_check
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 dismiss_item_permissions_check
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 dismiss_item
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
7.33
1<?php
2/**
3 * REST API endpoint for retrieving JITMs from the WPCOM API via the Jetpack JITM class
4 * infrastructure.
5 *
6 * Replaces projects/packages/jitm/src/class-rest-api-endpoints.php.
7 *
8 * Available on:
9 * - Simple - via Dotcom Public API (https://public-api.wordpress.com/wpcom/v3/sites/{site_id}/jitm).
10 * - WoA and Jetpack connected sites - via local site REST API (https://myjetpackconnectedsite.com/wp-json/wpcom/v3/jitm)
11 *
12 * Utilises Jetpack classes to orchestrate the request and response handling.
13 * All JITM configuration happens on the Dotcom Simple codebase.
14 *
15 * @package automattic/jetpack
16 */
17
18use Automattic\Jetpack\Connection\REST_Connector;
19
20if ( ! defined( 'ABSPATH' ) ) {
21    exit( 0 );
22}
23
24/**
25 * Class WPCOM_REST_API_V3_Endpoint_JITM
26 */
27class WPCOM_REST_API_V3_Endpoint_JITM extends WP_REST_Controller {
28
29    /**
30     * Namespace prefix.
31     *
32     * @var string
33     */
34    public $namespace = 'wpcom/v3';
35
36    /**
37     * Endpoint base route.
38     *
39     * @var string
40     */
41    public $rest_base = 'jitm';
42
43    /**
44     * WPCOM_REST_API_V3_Endpoint_JITM constructor.
45     */
46    public function __construct() {
47        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
48    }
49
50    /**
51     * Register JITM routes.
52     */
53    public function register_routes() {
54        register_rest_route(
55            $this->namespace,
56            $this->rest_base,
57            array(
58                array(
59                    'methods'             => WP_REST_Server::READABLE,
60                    'callback'            => array( $this, 'get_item' ),
61                    'permission_callback' => array( $this, 'get_item_permissions_check' ),
62                    'args'                => array(
63                        'message_path'        => array(
64                            'required'          => true,
65                            'type'              => 'string',
66                            'description'       => __( 'The message path to fetch JITMs for', 'jetpack' ),
67                            'validate_callback' => 'rest_validate_request_arg',
68                        ),
69                        'query'               => array(
70                            'required'    => false,
71                            'type'        => 'string',
72                            'description' => __( 'Additional query parameters', 'jetpack' ),
73                        ),
74                        'full_jp_logo_exists' => array(
75                            'required'    => false,
76                            'type'        => 'boolean',
77                            'description' => __( 'Whether the full Jetpack logo exists', 'jetpack' ),
78                        ),
79                    ),
80                ),
81                array(
82                    'methods'             => WP_REST_Server::CREATABLE,
83                    'callback'            => array( $this, 'dismiss_item' ),
84                    'permission_callback' => array( $this, 'dismiss_item_permissions_check' ),
85                    'args'                => array(
86                        'id'            => array(
87                            'required'    => true,
88                            'type'        => 'string',
89                            'description' => __( 'The ID of the JITM to dismiss', 'jetpack' ),
90                        ),
91                        'feature_class' => array(
92                            'required'    => true,
93                            'type'        => 'string',
94                            'description' => __( 'The feature class of the JITM', 'jetpack' ),
95                        ),
96                    ),
97                ),
98            )
99        );
100    }
101
102    /**
103     * Retrieves the JITMs.
104     *
105     * @param WP_REST_Request $request Full details about the request.
106     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
107     */
108    public function get_item( $request ) {
109        $jitm = Automattic\Jetpack\JITMS\JITM::get_instance();
110
111        if ( ! $jitm->jitms_enabled() ) {
112            return rest_ensure_response( array() );
113        }
114
115        // add the search term to the query params if it exists
116        $query_param = $request['query'] ?? '';
117
118        // Disable the jetpack_user_auth_check filter on Dotcom Simple codebase.
119        // This allows the wpcom/v3/jitm endpoint to work for Simple sites.
120        // See fbhepr%2Skers%2Sjcpbz%2Sjc%2Qpbagrag%2Serfg%2Qncv%2Qcyhtvaf%2Sraqcbvagf%2Swrgcnpx.cuc%3Se%3Q4580oq59%2374-og.
121        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
122            add_filter( 'rest_api_jitm_jetpack_user_auth_check', '__return_true' );
123        }
124
125        $messages = $jitm->get_messages(
126            $request['message_path'],
127            urldecode_deep( array( 'query' => $query_param ) ),
128            'true' === $request['full_jp_logo_exists']
129        );
130
131        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
132            remove_filter( 'rest_api_jitm_jetpack_user_auth_check', '__return_true' );
133        }
134
135        return rest_ensure_response( $messages );
136    }
137
138    /**
139     * Checks if a given request has access to get JITMs.
140     *
141     * @param WP_REST_Request $request Full details about the request.
142     * @return true|WP_Error True if the request has permission to get JITMs, WP_Error object otherwise.
143     */
144    public function get_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
145        if ( ! current_user_can( 'read' ) ) {
146            return new WP_Error(
147                'invalid_user_permission_jetpack_get_jitm_message',
148                REST_Connector::get_user_permissions_error_msg(),
149                array( 'status' => rest_authorization_required_code() )
150            );
151        }
152
153        return true;
154    }
155
156    /**
157     * Checks if a given request has access to dismiss JITMs.
158     *
159     * @return true|WP_Error True if the request has permission to dismiss, WP_Error object otherwise.
160     */
161    public function dismiss_item_permissions_check() {
162        if ( ! current_user_can( 'read' ) ) {
163            return new WP_Error(
164                'invalid_user_permission_jetpack_delete_jitm_message',
165                REST_Connector::get_user_permissions_error_msg(),
166                array( 'status' => rest_authorization_required_code() )
167            );
168        }
169
170        return true;
171    }
172
173    /**
174     * Dismisses a JITM message.
175     *
176     * @param WP_REST_Request $request Full details about the request.
177     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
178     */
179    public function dismiss_item( $request ) {
180        $jitm = Automattic\Jetpack\JITMS\JITM::get_instance();
181
182        if ( ! $jitm->jitms_enabled() ) {
183            // Boolean return matches return type of $jitm->dismiss().
184            // Not returning a WP_Error avoids a 400 response code
185            // and allows the dismiss action to be silently ignored.
186            return rest_ensure_response( true );
187        }
188
189        // Disable the jetpack_user_auth_check filter on Dotcom Simple codebase.
190        // This allows the wpcom/v3/jitm endpoint to work for Simple sites.
191        // See fbhepr%2Skers%2Sjcpbz%2Sjc%2Qpbagrag%2Serfg%2Qncv%2Qcyhtvaf%2Sraqcbvagf%2Swrgcnpx.cuc%3Se%3Q4580oq59%2374-og.
192        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
193            add_filter( 'rest_api_jitm_jetpack_user_auth_check', '__return_true' );
194        }
195
196        $result = $jitm->dismiss( $request['id'], $request['feature_class'] );
197
198        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
199            remove_filter( 'rest_api_jitm_jetpack_user_auth_check', '__return_true' );
200        }
201
202        return rest_ensure_response( $result );
203    }
204}
205
206// This function is badly named since it works for all versions of the REST API.
207wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V3_Endpoint_JITM' );