PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.2
Jetpack – WP Security, Backup, Speed, & Growth v16.2
16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 All 502 releases
jetpack / _inc / lib / core-api / wpcom-endpoints / class-wpcom-rest-api-v2-endpoint-email-preview.php

class-wpcom-rest-api-v2-endpoint-email-preview.php in Jetpack – WP Security, Backup, Speed, & Growth 16.2, at _inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-email-preview.php

184 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Email Preview endpoint for the WordPress.com REST API.
4 *
5 * @package automattic/jetpack
6 */
7
8 use Automattic\Jetpack\Connection\Manager;
9 use Automattic\Jetpack\Connection\Traits\WPCOM_REST_API_Proxy_Request;
10 use Automattic\Jetpack\Status\Host;
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit( 0 );
14 }
15
16 /**
17 * Class WPCOM_REST_API_V2_Endpoint_Email_Preview
18 *
19 * Returns an email preview given a post id.
20 */
21 class WPCOM_REST_API_V2_Endpoint_Email_Preview extends WP_REST_Controller {
22
23 use WPCOM_REST_API_Proxy_Request;
24
25 /**
26 * Constructor.
27 */
28 public function __construct() {
29 $this->base_api_path = 'wpcom';
30 $this->version = 'v2';
31 $this->namespace = $this->base_api_path . '/' . $this->version;
32 $this->rest_base = '/email-preview';
33 $this->wpcom_is_wpcom_only_endpoint = true;
34 $this->wpcom_is_site_specific_endpoint = true;
35
36 add_action( 'rest_api_init', array( $this, 'register_routes' ) );
37 }
38
39 /**
40 * Registers the routes for email preview.
41 *
42 * @see register_rest_route()
43 */
44 public function register_routes() {
45 $options = array(
46 'show_in_index' => true,
47 'methods' => 'GET',
48 'callback' => array( $this, 'email_preview' ),
49 'permission_callback' => array( $this, 'permissions_check' ),
50 'args' => array(
51 'post_id' => array(
52 'description' => __( 'Unique identifier for the post.', 'jetpack' ),
53 'type' => 'integer',
54 ),
55 'access' => array(
56 'description' => __( 'Access level.', 'jetpack' ),
57 'enum' => array( 'everybody', 'subscribers', 'paid_subscribers' ),
58 'default' => 'everybody',
59 'validate_callback' => function ( $param ) {
60 return in_array(
61 $param,
62 array( 'everybody', 'subscribers', 'paid_subscribers' ),
63 true
64 );
65 },
66 ),
67 ),
68 );
69
70 register_rest_route(
71 $this->namespace,
72 $this->rest_base,
73 $options
74 );
75 }
76
77 /**
78 * Checks whether the request may render an email preview.
79 *
80 * The preview only renders the site's own post, so it needs the site to be connected
81 * but not the requesting user. The `edit_post` capability check is the authorization.
82 *
83 * @param WP_REST_Request $request Full data about the request.
84 *
85 * @return true|WP_Error True if the request may render the preview, WP_Error object otherwise.
86 */
87 public function permissions_check( $request ) {
88 $is_wpcom_simple = ( new Host() )->is_wpcom_simple();
89
90 // On a self-hosted site, the site must be connected before we can proxy the preview to WordPress.com.
91 // This uses its own error code (not the user-connection one) so the client can tell the two apart.
92 if ( ! $is_wpcom_simple && ! ( new Manager() )->is_connected() ) {
93 return new WP_Error(
94 'rest_cannot_view_email_preview',
95 __( 'Please connect your site to WordPress.com to preview emails.', 'jetpack' ),
96 array( 'status' => rest_authorization_required_code() )
97 );
98 }
99
100 $post = get_post( $request->get_param( 'post_id' ) );
101
102 if ( ! $post ) {
103 return new \WP_Error(
104 'post_not_found',
105 __( 'Post not found.', 'jetpack' ),
106 array( 'status' => 404 )
107 );
108 }
109
110 // Authorize any user who can edit the post: the local editor on self-hosted, a user-token request on WordPress.com.
111 if ( current_user_can( 'edit_post', $post->ID ) ) {
112 return true;
113 }
114
115 // On WordPress.com, a blog-token proxy authenticates as user 0 and fails the edit_post check
116 // above, so authorize it by site ownership instead. The self-hosted endpoint already verified a
117 // local editor could edit the post, and the blog token never reaches the browser.
118 if ( $is_wpcom_simple && $this->is_authorized_blog_token_request() ) {
119 return true;
120 }
121
122 return new WP_Error(
123 'rest_forbidden_context',
124 __( 'Sorry, you are not allowed to preview emails on this site.', 'jetpack' ),
125 array( 'status' => rest_authorization_required_code() )
126 );
127 }
128
129 /**
130 * Whether the request is a valid blog-token request authorized for the current site.
131 *
132 * Runs on WordPress.com, where a proxied blog token authenticates as user 0.
133 *
134 * @return bool True if the request is authorized for the current Jetpack site.
135 */
136 private function is_authorized_blog_token_request() {
137 if ( ! is_jetpack_site( get_current_blog_id() ) ) {
138 return false;
139 }
140
141 if ( ! class_exists( 'WPCOM_REST_API_V2_Endpoint_Jetpack_Auth' ) ) {
142 require_once dirname( __DIR__ ) . '/rest-api-plugins/endpoints/jetpack-auth.php';
143 }
144
145 $jp_auth_endpoint = new WPCOM_REST_API_V2_Endpoint_Jetpack_Auth();
146
147 return true === $jp_auth_endpoint->is_jetpack_authorized_for_site();
148 }
149
150 /**
151 * Returns an email preview of a post, or proxies the request to WordPress.com on non-wpcom sites.
152 *
153 * @param WP_REST_Request $request Full data about the request.
154 *
155 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
156 */
157 public function email_preview( $request ) {
158 // On a non-wpcom site, proxy to WordPress.com with the user's token, falling back to the site's blog token.
159 if ( ! ( new Host() )->is_wpcom_simple() ) {
160 return $this->proxy_request_to_wpcom( $request, '', 'user', true );
161 }
162
163 $post_id = $request['post_id'];
164 $access = $request['access'];
165 $post = get_post( $post_id );
166 return rest_ensure_response(
167 array(
168 /**
169 * Filters the generated email preview HTML.
170 *
171 * @since 13.8
172 *
173 * @param string $html The generated HTML for the email preview.
174 * @param WP_Post $post The post object.
175 * @param string $access The access level.
176 */
177 'html' => apply_filters( 'jetpack_generate_email_preview_html', '', $post, $access ),
178 )
179 );
180 }
181 }
182
183 wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Email_Preview' );
184