Completed
Push — fix/shortlink-button ( a110fb...ee61e1 )
by Jeremy
12:15 queued 05:25
created

Jetpack_Post_By_Email::process_api_request()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 8
nop 1
dl 0
loc 26
rs 9.1928
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class Jetpack_Post_By_Email
4
 *
5
 * @package Jetpack
6
 */
7
8
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
9
10
/**
11
 * Class Jetpack_Post_By_Email
12
 */
13
class Jetpack_Post_By_Email {
14
	/**
15
	 * Initialize PBE.
16
	 *
17
	 * @return Jetpack_Post_By_Email
18
	 */
19
	public static function init() {
20
		static $instance = null;
21
22
		if ( ! $instance ) {
23
			$instance = new Jetpack_Post_By_Email();
24
		}
25
26
		return $instance;
27
	}
28
29
	/**
30
	 * Singleton
31
	 */
32
	private function __construct() {
33
		add_action( 'init', array( &$this, 'action_init' ) );
34
	}
35
36
	/**
37
	 * Adds hooks for PBE.
38
	 */
39
	public function action_init() {
40
		if ( ! current_user_can( 'edit_posts' ) ) {
41
			return;
42
		}
43
44
		add_action( 'profile_personal_options', array( &$this, 'user_profile' ) );
45
		add_action( 'admin_print_scripts-profile.php', array( &$this, 'profile_scripts' ) );
46
47
		add_action( 'wp_ajax_jetpack_post_by_email_enable', array( &$this, 'create_post_by_email_address' ) );
48
		add_action( 'wp_ajax_jetpack_post_by_email_regenerate', array( &$this, 'regenerate_post_by_email_address' ) );
49
		add_action( 'wp_ajax_jetpack_post_by_email_disable', array( &$this, 'delete_post_by_email_address' ) );
50
	}
51
52
	/**
53
	 * Enqueues scripts for user profile page.
54
	 */
55
	public function profile_scripts() {
56
		wp_enqueue_script( 'post-by-email', plugins_url( 'post-by-email.js', __FILE__ ), array( 'jquery' ), JETPACK__VERSION, true );
57
		wp_localize_script(
58
			'post-by-email',
59
			'pbeVars',
60
			array(
61
				'rest_nonce' => wp_create_nonce( 'wp_rest' ),
62
			)
63
		);
64
		wp_enqueue_style( 'post-by-email', plugins_url( 'post-by-email.css', __FILE__ ), array(), JETPACK__VERSION );
65
		wp_style_add_data( 'post-by-email', 'jetpack-inline', true );
66
	}
67
68
	/**
69
	 * Check if the user is connected.
70
	 *
71
	 * @return bool True if connected. False if not.
72
	 */
73
	public function check_user_connection() {
74
		$user_token = ( new Connection_Manager() )->get_access_token( get_current_user_id() );
75
76
		$is_user_connected = $user_token && ! is_wp_error( $user_token );
77
78
		// If the user is already connected via Jetpack, then we're good.
79
		if ( $is_user_connected ) {
80
			return true;
81
		}
82
83
		return false;
84
	}
85
86
	/**
87
	 * Adds field to user profile page.
88
	 */
89
	public function user_profile() {
90
		$blog_name = get_bloginfo( 'blogname' );
91
		if ( empty( $blog_name ) ) {
92
			$blog_name = home_url( '/' );
93
		}
94
95
		?>
96
		<div id="post-by-email" class="jetpack-targetable">
97
			<h3><?php esc_html_e( 'Post by Email', 'jetpack' ); ?></h3>
98
			<table class="form-table">
99
				<tr>
100
					<th scope="row"><?php esc_html_e( 'Email Address', 'jetpack' ); ?><span id="jp-pbe-spinner" class="spinner"></span></th>
101
					<td>
102
						<div id="jp-pbe-error" class="jetpack-inline-error"></div>
103
						<?php
104
105
						if ( $this->check_user_connection() ) {
106
							$email = $this->get_post_by_email_address();
107
108
							$enable_button_style = empty( $email ) ? '' : 'display: none;';
109
							$info_style          = empty( $email ) ? 'display: none;' : '';
110
							?>
111
112
							<input type="button" name="jp-pbe-enable" id="jp-pbe-enable" class="button" value="<?php esc_attr_e( 'Enable Post By Email', 'jetpack' ); ?>" style="<?php echo esc_attr( $enable_button_style ); ?>" />
113
							<div id="jp-pbe-info" style="<?php echo esc_attr( $info_style ); ?>">
114
								<p id="jp-pbe-email-wrapper">
115
									<input type="text" id="jp-pbe-email" value="<?php echo esc_attr( $email ); ?>" readonly="readonly" class="regular-text" />
116
									<span class="description"><a target="_blank" href="https://jetpack.com/support/post-by-email/"><?php esc_html_e( 'More information', 'jetpack' ); ?></a></span>
117
								</p>
118
								<p>
119
									<input type="button" name="jp-pbe-regenerate" id="jp-pbe-regenerate" class="button" value="<?php esc_attr_e( 'Regenerate Address', 'jetpack' ); ?> " />
120
									<input type="button" name="jp-pbe-disable" id="jp-pbe-disable" class="button" value="<?php esc_attr_e( 'Disable Post By Email', 'jetpack' ); ?> " />
121
								</p>
122
							</div>
123
							<?php
124
						} else {
125
							$jetpack = Jetpack::init();
126
							?>
127
128
							<p class="jetpack-inline-message">
129
								<?php
130
								printf(
131
									/* translators: Placeholder is the site's name from WordPress settings. */
132
									esc_html( wptexturize( __( 'To use Post By Email, you need to link your %s account to your WordPress.com account.', 'jetpack' ) ) ),
133
									'<strong>' . esc_html( $blog_name ) . '</strong>'
134
								);
135
								?>
136
								<br />
137
								<?php echo esc_html( wptexturize( __( "If you don't have a WordPress.com account yet, you can sign up for free in just a few seconds.", 'jetpack' ) ) ); ?>
138
							</p>
139
							<p>
140
								<a href="<?php echo esc_url( $jetpack->build_connect_url( false, get_edit_profile_url( get_current_user_id() ) . '#post-by-email', 'unlinked-user-pbe' ) ); ?>" class="button button-connector" id="wpcom-connect"><?php esc_html_e( 'Link account with WordPress.com', 'jetpack' ); ?></a>
141
							</p>
142
							<?php
143
						}
144
						?>
145
					</td>
146
				</tr>
147
			</table>
148
		</div>
149
		<?php
150
	}
151
152
	/**
153
	 * XMLRPC Query to WP.com for PBE e-mail address for user.
154
	 *
155
	 * @return string|null PBE E-mail Address or null on error.
156
	 */
157
	public function get_post_by_email_address() {
158
		$xml = $this->init_rest_connection();
159
160
		$xml->query( 'jetpack.getPostByEmailAddress' );
161
162
		if ( $xml->isError() ) {
163
			return null;
164
		}
165
166
		$response = $xml->getResponse();
167
		if ( empty( $response ) ) {
168
			return null;
169
		}
170
171
		return $response;
172
	}
173
174
	/**
175
	 * Process the REST API request to modify the "Post by Email" settings.
176
	 *
177
	 * @param string $action Allowed values: 'create', 'regenerate', 'delete'.
178
	 *
179
	 * @return array|false
180
	 */
181
	public function process_api_request( $action ) {
182
		$endpoint      = null;
183
		$error_message = esc_html__( 'Please try again later.', 'jetpack' );
184
		$result        = false;
185
186
		switch ( $action ) {
187
			case 'create':
188
				$endpoint      = 'jetpack.createPostByEmailAddress';
189
				$error_message = esc_html__( 'Unable to create the Post by Email address. Please try again later.', 'jetpack' );
190
				break;
191
			case 'regenerate':
192
				$endpoint      = 'jetpack.regeneratePostByEmailAddress';
193
				$error_message = esc_html__( 'Unable to regenerate the Post by Email address. Please try again later.', 'jetpack' );
194
				break;
195
			case 'delete':
196
				$endpoint      = 'jetpack.deletePostByEmailAddress';
197
				$error_message = esc_html__( 'Unable to delete the Post by Email address. Please try again later.', 'jetpack' );
198
				break;
199
		}
200
201
		if ( $endpoint ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $endpoint of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
202
			$result = $this->process_rest_proxy_request( $endpoint, $error_message );
203
		}
204
205
		return $result;
206
	}
207
208
	/**
209
	 * AJAX endpoint to create a new e-mail address.
210
	 */
211
	public function create_post_by_email_address() {
212
		_doing_it_wrong( __METHOD__, esc_html__( "Use REST API endpoint '/wp-json/jetpack/v4/settings' instead.", 'jetpack' ), 'jetpack-8.4' );
213
214
		self::process_ajax_proxy_request(
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Post_By_Email::p...ss_ajax_proxy_request() has been deprecated.

This method has been deprecated.

Loading history...
215
			'jetpack.createPostByEmailAddress',
216
			__( 'Unable to create your Post By Email address. Please try again later.', 'jetpack' )
217
		);
218
	}
219
220
	/**
221
	 * AJAX endpoint to regenerate PBE e-mail address.
222
	 */
223
	public function regenerate_post_by_email_address() {
224
		_doing_it_wrong( __METHOD__, esc_html__( "Use REST API endpoint '/wp-json/jetpack/v4/settings' instead.", 'jetpack' ), 'jetpack-8.4' );
225
226
		self::process_ajax_proxy_request(
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Post_By_Email::p...ss_ajax_proxy_request() has been deprecated.

This method has been deprecated.

Loading history...
227
			'jetpack.regeneratePostByEmailAddress',
228
			__( 'Unable to regenerate your Post By Email address. Please try again later.', 'jetpack' )
229
		);
230
	}
231
232
	/**
233
	 * AJAX endpoint to delete a PBE e-mail address.
234
	 */
235
	public function delete_post_by_email_address() {
236
		_doing_it_wrong( __METHOD__, esc_html__( "Use REST API endpoint '/wp-json/jetpack/v4/settings' instead.", 'jetpack' ), 'jetpack-8.4' );
237
238
		self::process_ajax_proxy_request(
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Post_By_Email::p...ss_ajax_proxy_request() has been deprecated.

This method has been deprecated.

Loading history...
239
			'jetpack.deletePostByEmailAddress',
240
			__( 'Unable to disable your Post By Email address. Please try again later.', 'jetpack' )
241
		);
242
	}
243
244
	/**
245
	 * The AJAX proxying method for backward compatibility.
246
	 * To be removed in the upcoming versions.
247
	 *
248
	 * @param string $endpoint Jetpack API endpoint.
249
	 * @param string $error_message Error message to be returned if something goes wrong.
250
	 *
251
	 * @deprecated
252
	 */
253
	public function __process_ajax_proxy_request( $endpoint, $error_message ) { // phpcs:ignore
254
		$this->process_ajax_proxy_request( $endpoint, $error_message );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Post_By_Email::p...ss_ajax_proxy_request() has been deprecated.

This method has been deprecated.

Loading history...
255
	}
256
257
	/**
258
	 * Back end function to abstract the xmlrpc function calls to wpcom.
259
	 *
260
	 * @param string $endpoint Jetpack API endpoint.
261
	 * @param string $error_message Error message to be returned if something goes wrong.
262
	 *
263
	 * @deprecated
264
	 */
265
	private function process_ajax_proxy_request( $endpoint, $error_message ) {
266
		_deprecated_function( __METHOD__, 'jetpack-8.4', '_process_rest_proxy_request' );
267
268
		if ( ! current_user_can( 'edit_posts' ) ) {
269
			wp_send_json_error( $error_message );
270
		}
271
		if ( empty( $_REQUEST['pbe_nonce'] ) || ! wp_verify_nonce( $_REQUEST['pbe_nonce'], $endpoint ) ) {
272
			wp_send_json_error( $error_message );
273
		}
274
275
		$xml = $this->init_rest_connection();
276
		$xml->query( $endpoint );
277
278
		if ( $xml->isError() ) {
279
			wp_send_json_error( $error_message );
280
		}
281
282
		$response = $xml->getResponse();
283
		if ( empty( $response ) ) {
284
			wp_send_json_error( $error_message );
285
		}
286
287
		// Will be used only in Jetpack_Core_Json_Api_Endpoints::get_remote_value.
288
		update_option( 'post_by_email_address' . get_current_user_id(), $response );
289
290
		wp_send_json_success( $response );
291
	}
292
293
	/**
294
	 * Calls WPCOM through authenticated request to create, regenerate or delete the Post by Email address.
295
	 *
296
	 * @since 4.3.0
297
	 *
298
	 * @param string $endpoint Process to call on WPCOM to create, regenerate or delete the Post by Email address.
299
	 * @param string $error    Error message to return.
300
	 *
301
	 * @return array
302
	 */
303
	private function process_rest_proxy_request( $endpoint, $error ) {
304
		if ( ! current_user_can( 'edit_posts' ) ) {
305
			return array( 'message' => $error );
306
		}
307
308
		$xml = $this->init_rest_connection();
309
310
		$xml->query( $endpoint );
311
312
		if ( $xml->isError() ) {
313
			return array( 'message' => $error );
314
		}
315
316
		$response = $xml->getResponse();
317
		if ( empty( $response ) ) {
318
			return array( 'message' => $error );
319
		}
320
321
		// Used only in Jetpack_Core_Json_Api_Endpoints::get_remote_value.
322
		update_option( 'post_by_email_address' . get_current_user_id(), $response );
323
324
		return $response;
325
	}
326
327
	/**
328
	 * Initialize the IXR client
329
	 *
330
	 * @return Jetpack_IXR_Client
331
	 */
332
	private function init_rest_connection() {
333
		return new Jetpack_IXR_Client( array( 'user_id' => get_current_user_id() ) );
334
	}
335
}
336