|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* The Backup Rest Controller class. |
|
4
|
|
|
* Registers the REST routes for Backup. |
|
5
|
|
|
* |
|
6
|
|
|
* @package automattic/jetpack-backup |
|
7
|
|
|
*/ |
|
8
|
|
|
|
|
9
|
|
|
namespace Automattic\Jetpack\Backup; |
|
10
|
|
|
|
|
11
|
|
|
use Automattic\Jetpack\Connection\Rest_Authentication; |
|
12
|
|
|
use Automattic\Jetpack\Sync\Actions as Sync_Actions; |
|
13
|
|
|
use WP_Error; |
|
14
|
|
|
use WP_REST_Request; |
|
15
|
|
|
use WP_REST_Server; |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* Registers the REST routes for Backup. |
|
19
|
|
|
*/ |
|
20
|
|
|
class REST_Controller { |
|
21
|
|
|
/** |
|
22
|
|
|
* Registers the REST routes for Backup. |
|
23
|
|
|
* |
|
24
|
|
|
* @access public |
|
25
|
|
|
* @static |
|
26
|
|
|
*/ |
|
27
|
|
|
public static function register_rest_routes() { |
|
28
|
|
|
// Install a Helper Script to assist Jetpack Backup fetch data. |
|
29
|
|
|
register_rest_route( |
|
30
|
|
|
'jetpack/v4', |
|
31
|
|
|
'/backup-helper-script', |
|
32
|
|
|
array( |
|
33
|
|
|
'methods' => WP_REST_Server::CREATABLE, |
|
34
|
|
|
'callback' => __CLASS__ . '::install_backup_helper_script', |
|
35
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
36
|
|
|
'args' => array( |
|
37
|
|
|
'helper' => array( |
|
38
|
|
|
'description' => __( 'base64 encoded Backup Helper Script body.', 'jetpack' ), |
|
39
|
|
|
'type' => 'string', |
|
40
|
|
|
'required' => true, |
|
41
|
|
|
), |
|
42
|
|
|
), |
|
43
|
|
|
) |
|
44
|
|
|
); |
|
45
|
|
|
|
|
46
|
|
|
// Delete a Backup Helper Script. |
|
47
|
|
|
register_rest_route( |
|
48
|
|
|
'jetpack/v4', |
|
49
|
|
|
'/backup-helper-script', |
|
50
|
|
|
array( |
|
51
|
|
|
'methods' => WP_REST_Server::DELETABLE, |
|
52
|
|
|
'callback' => __CLASS__ . '::delete_backup_helper_script', |
|
53
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
54
|
|
|
'args' => array( |
|
55
|
|
|
'path' => array( |
|
56
|
|
|
'description' => __( 'Path to Backup Helper Script', 'jetpack' ), |
|
57
|
|
|
'type' => 'string', |
|
58
|
|
|
'required' => true, |
|
59
|
|
|
), |
|
60
|
|
|
), |
|
61
|
|
|
) |
|
62
|
|
|
); |
|
63
|
|
|
|
|
64
|
|
|
// Fetch a backup of a database object, along with all of its metadata. |
|
65
|
|
|
register_rest_route( |
|
66
|
|
|
'jetpack/v4', |
|
67
|
|
|
'/database-object/backup', |
|
68
|
|
|
array( |
|
69
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
70
|
|
|
'callback' => __CLASS__ . '::fetch_database_object_backup', |
|
71
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
72
|
|
|
'args' => array( |
|
73
|
|
|
'object_type' => array( |
|
74
|
|
|
'description' => __( 'Type of object to fetch from the database', 'jetpack' ), |
|
75
|
|
|
'required' => true, |
|
76
|
|
|
'validate_callback' => function ( $value ) { |
|
77
|
|
|
if ( ! is_string( $value ) ) { |
|
78
|
|
|
return new WP_Error( |
|
79
|
|
|
'rest_invalid_param', |
|
|
|
|
|
|
80
|
|
|
__( 'The object_type argument must be a non-empty string.', 'jetpack' ), |
|
81
|
|
|
array( 'status' => 400 ) |
|
82
|
|
|
); |
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
$allowed_object_types = array_keys( self::get_allowed_object_types() ); |
|
86
|
|
|
|
|
87
|
|
View Code Duplication |
if ( ! in_array( $value, $allowed_object_types, true ) ) { |
|
88
|
|
|
return new WP_Error( |
|
89
|
|
|
'rest_invalid_param', |
|
|
|
|
|
|
90
|
|
|
sprintf( |
|
91
|
|
|
/* translators: %s: comma-separated list of allowed object types */ |
|
92
|
|
|
__( 'The object_type argument should be one of %s', 'jetpack' ), |
|
93
|
|
|
implode( ', ', $allowed_object_types ) |
|
94
|
|
|
), |
|
95
|
|
|
array( 'status' => 400 ) |
|
96
|
|
|
); |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
return true; |
|
100
|
|
|
}, |
|
101
|
|
|
), |
|
102
|
|
|
'object_id' => array( |
|
103
|
|
|
'description' => __( 'ID of the database object to fetch', 'jetpack' ), |
|
104
|
|
|
'type' => 'integer', |
|
105
|
|
|
'required' => true, |
|
106
|
|
|
), |
|
107
|
|
|
), |
|
108
|
|
|
) |
|
109
|
|
|
); |
|
110
|
|
|
|
|
111
|
|
|
// Fetch a backup of an option. |
|
112
|
|
|
register_rest_route( |
|
113
|
|
|
'jetpack/v4', |
|
114
|
|
|
'/options/backup', |
|
115
|
|
|
array( |
|
116
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
117
|
|
|
'callback' => __CLASS__ . '::fetch_options_backup', |
|
118
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
119
|
|
|
'args' => array( |
|
120
|
|
|
'name' => array( |
|
121
|
|
|
'description' => __( 'One or more option names to include in the backup', 'jetpack' ), |
|
122
|
|
|
'validate_callback' => function ( $value ) { |
|
123
|
|
|
$is_valid = is_array( $value ) || is_string( $value ); |
|
124
|
|
|
if ( ! $is_valid ) { |
|
125
|
|
|
return new WP_Error( 'rest_invalid_param', __( 'The name argument should be an option name or an array of option names', 'jetpack' ), array( 'status' => 400 ) ); |
|
|
|
|
|
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
return true; |
|
129
|
|
|
}, |
|
130
|
|
|
'required' => true, |
|
131
|
|
|
), |
|
132
|
|
|
), |
|
133
|
|
|
) |
|
134
|
|
|
); |
|
135
|
|
|
|
|
136
|
|
|
// Fetch a backup of a comment, along with all of its metadata. |
|
137
|
|
|
register_rest_route( |
|
138
|
|
|
'jetpack/v4', |
|
139
|
|
|
'/comments/(?P<id>\d+)/backup', |
|
140
|
|
|
array( |
|
141
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
142
|
|
|
'callback' => __CLASS__ . '::fetch_comment_backup', |
|
143
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
144
|
|
|
) |
|
145
|
|
|
); |
|
146
|
|
|
|
|
147
|
|
|
// Fetch a backup of a post, along with all of its metadata. |
|
148
|
|
|
register_rest_route( |
|
149
|
|
|
'jetpack/v4', |
|
150
|
|
|
'/posts/(?P<id>\d+)/backup', |
|
151
|
|
|
array( |
|
152
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
153
|
|
|
'callback' => __CLASS__ . '::fetch_post_backup', |
|
154
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
155
|
|
|
) |
|
156
|
|
|
); |
|
157
|
|
|
|
|
158
|
|
|
// Fetch a backup of a term, along with all of its metadata. |
|
159
|
|
|
register_rest_route( |
|
160
|
|
|
'jetpack/v4', |
|
161
|
|
|
'/terms/(?P<id>\d+)/backup', |
|
162
|
|
|
array( |
|
163
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
164
|
|
|
'callback' => __CLASS__ . '::fetch_term_backup', |
|
165
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
166
|
|
|
) |
|
167
|
|
|
); |
|
168
|
|
|
|
|
169
|
|
|
// Fetch a backup of a user, along with all of its metadata. |
|
170
|
|
|
register_rest_route( |
|
171
|
|
|
'jetpack/v4', |
|
172
|
|
|
'/users/(?P<id>\d+)/backup', |
|
173
|
|
|
array( |
|
174
|
|
|
'methods' => WP_REST_Server::READABLE, |
|
175
|
|
|
'callback' => __CLASS__ . '::fetch_user_backup', |
|
176
|
|
|
'permission_callback' => __CLASS__ . '::backup_permissions_callback', |
|
177
|
|
|
) |
|
178
|
|
|
); |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
/** |
|
182
|
|
|
* The Backup endpoints should only be available via site-level authentication. |
|
183
|
|
|
* This means that the corresponding endpoints can only be accessible from WPCOM. |
|
184
|
|
|
* |
|
185
|
|
|
* @access public |
|
186
|
|
|
* @static |
|
187
|
|
|
* |
|
188
|
|
|
* @return bool|WP_Error True if a blog token was used to sign the request, WP_Error otherwise. |
|
189
|
|
|
*/ |
|
190
|
|
View Code Duplication |
public static function backup_permissions_callback() { |
|
191
|
|
|
if ( Rest_Authentication::is_signed_with_blog_token() ) { |
|
192
|
|
|
return true; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
$error_msg = esc_html__( |
|
196
|
|
|
'You are not allowed to perform this action.', |
|
197
|
|
|
'jetpack' |
|
198
|
|
|
); |
|
199
|
|
|
|
|
200
|
|
|
return new WP_Error( 'rest_forbidden', $error_msg, array( 'status' => rest_authorization_required_code() ) ); |
|
|
|
|
|
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
/** |
|
204
|
|
|
* Install the Backup Helper Script. |
|
205
|
|
|
* |
|
206
|
|
|
* @access public |
|
207
|
|
|
* @static |
|
208
|
|
|
* |
|
209
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
210
|
|
|
* @return array|WP_Error Returns the result of Helper Script installation. Returns one of: |
|
211
|
|
|
* - WP_Error on failure, or |
|
212
|
|
|
* - An array with installation info on success: |
|
213
|
|
|
* 'path' (string) The sinstallation path. |
|
214
|
|
|
* 'url' (string) The access url. |
|
215
|
|
|
* 'abspath' (string) The abspath. |
|
216
|
|
|
*/ |
|
217
|
|
|
public static function install_backup_helper_script( $request ) { |
|
218
|
|
|
$helper_script = $request->get_param( 'helper' ); |
|
219
|
|
|
|
|
220
|
|
|
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode |
|
221
|
|
|
$helper_script = base64_decode( $helper_script ); |
|
222
|
|
|
if ( ! $helper_script ) { |
|
223
|
|
|
return new WP_Error( 'invalid_args', __( 'Helper script body must be base64 encoded', 'jetpack' ), 400 ); |
|
|
|
|
|
|
224
|
|
|
} |
|
225
|
|
|
|
|
226
|
|
|
$installation_info = Helper_Script_Manager::install_helper_script( $helper_script ); |
|
227
|
|
|
Helper_Script_Manager::cleanup_expired_helper_scripts(); |
|
228
|
|
|
|
|
229
|
|
|
// Include ABSPATH with successful result. |
|
230
|
|
|
if ( ! is_wp_error( $installation_info ) ) { |
|
231
|
|
|
$installation_info['abspath'] = ABSPATH; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
return rest_ensure_response( $installation_info ); |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* Delete a Backup Helper Script. |
|
239
|
|
|
* |
|
240
|
|
|
* @access public |
|
241
|
|
|
* @static |
|
242
|
|
|
* |
|
243
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
244
|
|
|
* @return array An array with 'success' key indicating the result of the delete operation. |
|
245
|
|
|
*/ |
|
246
|
|
|
public static function delete_backup_helper_script( $request ) { |
|
247
|
|
|
$path_to_helper_script = $request->get_param( 'path' ); |
|
248
|
|
|
|
|
249
|
|
|
$deleted = Helper_Script_Manager::delete_helper_script( $path_to_helper_script ); |
|
250
|
|
|
Helper_Script_Manager::cleanup_expired_helper_scripts(); |
|
251
|
|
|
|
|
252
|
|
|
return rest_ensure_response( |
|
253
|
|
|
array( |
|
254
|
|
|
'success' => $deleted, |
|
255
|
|
|
) |
|
256
|
|
|
); |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
/** |
|
260
|
|
|
* Fetch a backup of a database object, along with all of its metadata. |
|
261
|
|
|
* |
|
262
|
|
|
* @access public |
|
263
|
|
|
* @static |
|
264
|
|
|
* |
|
265
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
266
|
|
|
* @return array |
|
267
|
|
|
*/ |
|
268
|
|
|
public static function fetch_database_object_backup( $request ) { |
|
269
|
|
|
global $wpdb; |
|
270
|
|
|
|
|
271
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
272
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
273
|
|
|
|
|
274
|
|
|
$allowed_object_types = self::get_allowed_object_types(); |
|
275
|
|
|
// Safe to do this as we have already validated the object_type key exists in self::get_allowed_object_types(). |
|
276
|
|
|
$object_type = $allowed_object_types[ $request->get_param( 'object_type' ) ]; |
|
277
|
|
|
$object_id = $request->get_param( 'object_id' ); |
|
278
|
|
|
$table = $wpdb->prefix . $object_type['table']; |
|
279
|
|
|
$id_field = $object_type['id_field']; |
|
280
|
|
|
|
|
281
|
|
|
// Fetch the requested object. |
|
282
|
|
|
$object = $wpdb->get_row( |
|
283
|
|
|
$wpdb->prepare( |
|
284
|
|
|
'select * from `%s` where `%s` = %d', |
|
285
|
|
|
$table, |
|
286
|
|
|
$id_field, |
|
287
|
|
|
$object_id |
|
288
|
|
|
) |
|
289
|
|
|
); |
|
290
|
|
|
|
|
291
|
|
|
if ( empty( $object ) ) { |
|
292
|
|
|
return new WP_Error( 'object_not_found', __( 'Object not found', 'jetpack' ), array( 'status' => 404 ) ); |
|
|
|
|
|
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
$result = array( 'object' => $object ); |
|
296
|
|
|
|
|
297
|
|
|
// Fetch associated metadata (if this object type has any). |
|
298
|
|
|
if ( ! empty( $object_type['meta_type'] ) ) { |
|
299
|
|
|
$result['meta'] = get_metadata( $object_type['meta_type'], $object_id ); |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
// If there is a child linked table (eg: woocommerce_tax_rate_locations), fetch linked records. |
|
303
|
|
|
if ( ! empty( $object_type['child_table'] ) ) { |
|
304
|
|
|
$child_table = $wpdb->prefix . $object_type['child_table']; |
|
305
|
|
|
$child_id_field = $object_type['child_id_field']; |
|
306
|
|
|
|
|
307
|
|
|
$result['children'] = $wpdb->get_results( |
|
308
|
|
|
$wpdb->prepare( |
|
309
|
|
|
'select * from `%s` where `%s` = %d', |
|
310
|
|
|
$child_table, |
|
311
|
|
|
$child_id_field, |
|
312
|
|
|
$object_id |
|
313
|
|
|
) |
|
314
|
|
|
); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
return $result; |
|
318
|
|
|
} |
|
319
|
|
|
|
|
320
|
|
|
/** |
|
321
|
|
|
* Fetch a backup of an option. |
|
322
|
|
|
* |
|
323
|
|
|
* @access public |
|
324
|
|
|
* @static |
|
325
|
|
|
* |
|
326
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
327
|
|
|
* @return array |
|
328
|
|
|
*/ |
|
329
|
|
|
public static function fetch_options_backup( $request ) { |
|
330
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
331
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
332
|
|
|
|
|
333
|
|
|
$option_name = $request->get_param( 'name' ); |
|
334
|
|
|
if ( is_array( $option_name ) ) { |
|
335
|
|
|
$option_names = $option_name; |
|
336
|
|
|
} else { |
|
337
|
|
|
$option_names = array( $option_name ); |
|
338
|
|
|
} |
|
339
|
|
|
|
|
340
|
|
|
$options = array_map( 'self::get_option_row', $option_names ); |
|
341
|
|
|
return array( 'options' => $options ); |
|
342
|
|
|
} |
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* Fetch a backup of a comment, along with all of its metadata. |
|
346
|
|
|
* |
|
347
|
|
|
* @access public |
|
348
|
|
|
* @static |
|
349
|
|
|
* |
|
350
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
351
|
|
|
* @return array |
|
352
|
|
|
*/ |
|
353
|
|
|
public static function fetch_comment_backup( $request ) { |
|
354
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
355
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
356
|
|
|
|
|
357
|
|
|
$comment_id = $request['id']; |
|
358
|
|
|
$comment = get_comment( $comment_id ); |
|
359
|
|
|
|
|
360
|
|
|
if ( empty( $comment ) ) { |
|
361
|
|
|
return new WP_Error( 'comment_not_found', __( 'Comment not found', 'jetpack' ), array( 'status' => 404 ) ); |
|
|
|
|
|
|
362
|
|
|
} |
|
363
|
|
|
|
|
364
|
|
|
$allowed_keys = array( |
|
365
|
|
|
'comment_ID', |
|
366
|
|
|
'comment_post_ID', |
|
367
|
|
|
'comment_author', |
|
368
|
|
|
'comment_author_email', |
|
369
|
|
|
'comment_author_url', |
|
370
|
|
|
'comment_author_IP', |
|
371
|
|
|
'comment_date', |
|
372
|
|
|
'comment_date_gmt', |
|
373
|
|
|
'comment_content', |
|
374
|
|
|
'comment_karma', |
|
375
|
|
|
'comment_approved', |
|
376
|
|
|
'comment_agent', |
|
377
|
|
|
'comment_type', |
|
378
|
|
|
'comment_parent', |
|
379
|
|
|
'user_id', |
|
380
|
|
|
); |
|
381
|
|
|
|
|
382
|
|
|
$comment = array_intersect_key( $comment->to_array(), array_flip( $allowed_keys ) ); |
|
383
|
|
|
|
|
384
|
|
|
$comment_meta = get_comment_meta( $comment['comment_ID'] ); |
|
385
|
|
|
|
|
386
|
|
|
return array( |
|
387
|
|
|
'comment' => $comment, |
|
388
|
|
|
'meta' => is_array( $comment_meta ) ? $comment_meta : array(), |
|
389
|
|
|
); |
|
390
|
|
|
} |
|
391
|
|
|
|
|
392
|
|
|
/** |
|
393
|
|
|
* Fetch a backup of a post, along with all of its metadata. |
|
394
|
|
|
* |
|
395
|
|
|
* @access public |
|
396
|
|
|
* @static |
|
397
|
|
|
* |
|
398
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
399
|
|
|
* @return array |
|
400
|
|
|
*/ |
|
401
|
|
|
public static function fetch_post_backup( $request ) { |
|
402
|
|
|
global $wpdb; |
|
403
|
|
|
|
|
404
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
405
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
406
|
|
|
|
|
407
|
|
|
$post_id = $request['id']; |
|
408
|
|
|
$post = get_post( $post_id ); |
|
409
|
|
|
|
|
410
|
|
|
if ( empty( $post ) ) { |
|
411
|
|
|
return new WP_Error( 'post_not_found', __( 'Post not found', 'jetpack' ), array( 'status' => 404 ) ); |
|
|
|
|
|
|
412
|
|
|
} |
|
413
|
|
|
|
|
414
|
|
|
// Fetch terms associated with this post object. |
|
415
|
|
|
$terms = $wpdb->get_results( |
|
416
|
|
|
$wpdb->prepare( |
|
417
|
|
|
"SELECT term_taxonomy_id, term_order FROM {$wpdb->term_relationships} WHERE object_id = %d;", |
|
418
|
|
|
$post->ID |
|
419
|
|
|
) |
|
420
|
|
|
); |
|
421
|
|
|
|
|
422
|
|
|
return array( |
|
423
|
|
|
'post' => (array) $post, |
|
424
|
|
|
'meta' => get_post_meta( $post->ID ), |
|
425
|
|
|
'terms' => (array) $terms, |
|
426
|
|
|
); |
|
427
|
|
|
} |
|
428
|
|
|
|
|
429
|
|
|
/** |
|
430
|
|
|
* Fetch a backup of a term, along with all of its metadata. |
|
431
|
|
|
* |
|
432
|
|
|
* @access public |
|
433
|
|
|
* @static |
|
434
|
|
|
* |
|
435
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
436
|
|
|
* @return array |
|
437
|
|
|
*/ |
|
438
|
|
View Code Duplication |
public static function fetch_term_backup( $request ) { |
|
439
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
440
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
441
|
|
|
|
|
442
|
|
|
$term_id = $request['id']; |
|
443
|
|
|
$term = get_term( $term_id ); |
|
444
|
|
|
|
|
445
|
|
|
if ( empty( $term ) ) { |
|
446
|
|
|
return new WP_Error( 'term_not_found', __( 'Term not found', 'jetpack' ), array( 'status' => 404 ) ); |
|
|
|
|
|
|
447
|
|
|
} |
|
448
|
|
|
|
|
449
|
|
|
return array( |
|
450
|
|
|
'term' => (array) $term, |
|
451
|
|
|
'meta' => get_term_meta( $term_id ), |
|
452
|
|
|
); |
|
453
|
|
|
} |
|
454
|
|
|
|
|
455
|
|
|
/** |
|
456
|
|
|
* Fetch a backup of a user, along with all of its metadata. |
|
457
|
|
|
* |
|
458
|
|
|
* @access public |
|
459
|
|
|
* @static |
|
460
|
|
|
* |
|
461
|
|
|
* @param WP_REST_Request $request The request sent to the WP REST API. |
|
462
|
|
|
* @return array |
|
463
|
|
|
*/ |
|
464
|
|
View Code Duplication |
public static function fetch_user_backup( $request ) { |
|
465
|
|
|
// Disable Sync as this is a read-only operation and triggered by sync activity. |
|
466
|
|
|
Sync_Actions::mark_sync_read_only(); |
|
467
|
|
|
|
|
468
|
|
|
$user_id = $request['id']; |
|
469
|
|
|
$user = get_user_by( 'id', $user_id ); |
|
470
|
|
|
|
|
471
|
|
|
if ( empty( $user ) ) { |
|
472
|
|
|
return new WP_Error( 'user_not_found', __( 'User not found', 'jetpack' ), array( 'status' => 404 ) ); |
|
|
|
|
|
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
|
|
return array( |
|
476
|
|
|
'user' => $user->to_array(), |
|
477
|
|
|
'meta' => get_user_meta( $user->ID ), |
|
478
|
|
|
); |
|
479
|
|
|
} |
|
480
|
|
|
|
|
481
|
|
|
/** |
|
482
|
|
|
* Get allowed object types for the '/database-object/backup' endpoint. |
|
483
|
|
|
* |
|
484
|
|
|
* @access private |
|
485
|
|
|
* @static |
|
486
|
|
|
* |
|
487
|
|
|
* @return array |
|
488
|
|
|
*/ |
|
489
|
|
|
private static function get_allowed_object_types() { |
|
490
|
|
|
return array( |
|
491
|
|
|
'woocommerce_attribute' => array( |
|
492
|
|
|
'table' => 'woocommerce_attribute_taxonomies', |
|
493
|
|
|
'id_field' => 'attribute_id', |
|
494
|
|
|
), |
|
495
|
|
|
'woocommerce_downloadable_product_permission' => array( |
|
496
|
|
|
'table' => 'woocommerce_downloadable_product_permissions', |
|
497
|
|
|
'id_field' => 'permission_id', |
|
498
|
|
|
), |
|
499
|
|
|
'woocommerce_order_item' => array( |
|
500
|
|
|
'table' => 'woocommerce_order_items', |
|
501
|
|
|
'id_field' => 'order_item_id', |
|
502
|
|
|
'meta_type' => 'order_item', |
|
503
|
|
|
), |
|
504
|
|
|
'woocommerce_payment_token' => array( |
|
505
|
|
|
'table' => 'woocommerce_payment_tokens', |
|
506
|
|
|
'id_field' => 'token_id', |
|
507
|
|
|
'meta_type' => 'payment_token', |
|
508
|
|
|
), |
|
509
|
|
|
'woocommerce_tax_rate' => array( |
|
510
|
|
|
'table' => 'woocommerce_tax_rates', |
|
511
|
|
|
'id_field' => 'tax_rate_id', |
|
512
|
|
|
'child_table' => 'woocommerce_tax_rate_locations', |
|
513
|
|
|
'child_id_field' => 'tax_rate_id', |
|
514
|
|
|
), |
|
515
|
|
|
'woocommerce_webhook' => array( |
|
516
|
|
|
'table' => 'wc_webhooks', |
|
517
|
|
|
'id_field' => 'webhook_id', |
|
518
|
|
|
), |
|
519
|
|
|
); |
|
520
|
|
|
} |
|
521
|
|
|
|
|
522
|
|
|
/** |
|
523
|
|
|
* Fetch option row by option name. |
|
524
|
|
|
* |
|
525
|
|
|
* @access private |
|
526
|
|
|
* @static |
|
527
|
|
|
* |
|
528
|
|
|
* @param string $name The option name. |
|
529
|
|
|
* @return object|null Database query result as object format specified or null on failure. |
|
530
|
|
|
*/ |
|
531
|
|
|
private static function get_option_row( $name ) { |
|
532
|
|
|
global $wpdb; |
|
533
|
|
|
return $wpdb->get_row( $wpdb->prepare( "select * from `{$wpdb->options}` where option_name = %s", $name ) ); |
|
534
|
|
|
} |
|
535
|
|
|
} |
|
536
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.