changeset 7 | cf61fcea0001 |
parent 5 | 5e2f62d02dcd |
child 9 | 177826044cd9 |
6:490d5cc509ed | 7:cf61fcea0001 |
---|---|
1 <?php |
1 <?php |
2 /** |
2 /** |
3 * WordPress Core Ajax Handlers. |
3 * Administration API: Core Ajax handlers |
4 * |
4 * |
5 * @package WordPress |
5 * @package WordPress |
6 * @subpackage Administration |
6 * @subpackage Administration |
7 * @since 2.1.0 |
|
7 */ |
8 */ |
8 |
9 |
9 // |
10 // |
10 // No-privilege Ajax handlers. |
11 // No-privilege Ajax handlers. |
11 // |
12 // |
29 |
30 |
30 if ( ! empty($_POST['data']) ) { |
31 if ( ! empty($_POST['data']) ) { |
31 $data = wp_unslash( (array) $_POST['data'] ); |
32 $data = wp_unslash( (array) $_POST['data'] ); |
32 |
33 |
33 /** |
34 /** |
34 * Filter Heartbeat AJAX response in no-privilege environments. |
35 * Filters Heartbeat Ajax response in no-privilege environments. |
35 * |
36 * |
36 * @since 3.6.0 |
37 * @since 3.6.0 |
37 * |
38 * |
38 * @param array|object $response The no-priv Heartbeat response object or array. |
39 * @param array|object $response The no-priv Heartbeat response object or array. |
39 * @param array $data An array of data passed via $_POST. |
40 * @param array $data An array of data passed via $_POST. |
41 */ |
42 */ |
42 $response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id ); |
43 $response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id ); |
43 } |
44 } |
44 |
45 |
45 /** |
46 /** |
46 * Filter Heartbeat AJAX response when no data is passed. |
47 * Filters Heartbeat Ajax response when no data is passed. |
47 * |
48 * |
48 * @since 3.6.0 |
49 * @since 3.6.0 |
49 * |
50 * |
50 * @param array|object $response The Heartbeat response object or array. |
51 * @param array|object $response The Heartbeat response object or array. |
51 * @param string $screen_id The screen id. |
52 * @param string $screen_id The screen id. |
78 * Ajax handler for fetching a list table. |
79 * Ajax handler for fetching a list table. |
79 * |
80 * |
80 * @since 3.1.0 |
81 * @since 3.1.0 |
81 */ |
82 */ |
82 function wp_ajax_fetch_list() { |
83 function wp_ajax_fetch_list() { |
83 global $wp_list_table; |
|
84 |
|
85 $list_class = $_GET['list_args']['class']; |
84 $list_class = $_GET['list_args']['class']; |
86 check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' ); |
85 check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' ); |
87 |
86 |
88 $wp_list_table = _get_list_table( $list_class, array( 'screen' => $_GET['list_args']['screen']['id'] ) ); |
87 $wp_list_table = _get_list_table( $list_class, array( 'screen' => $_GET['list_args']['screen']['id'] ) ); |
89 if ( ! $wp_list_table ) |
88 if ( ! $wp_list_table ) { |
90 wp_die( 0 ); |
89 wp_die( 0 ); |
91 |
90 } |
92 if ( ! $wp_list_table->ajax_user_can() ) |
91 |
92 if ( ! $wp_list_table->ajax_user_can() ) { |
|
93 wp_die( -1 ); |
93 wp_die( -1 ); |
94 } |
|
94 |
95 |
95 $wp_list_table->ajax_response(); |
96 $wp_list_table->ajax_response(); |
96 |
97 |
97 wp_die( 0 ); |
98 wp_die( 0 ); |
98 } |
99 } |
127 $s = $s[count( $s ) - 1]; |
128 $s = $s[count( $s ) - 1]; |
128 } |
129 } |
129 $s = trim( $s ); |
130 $s = trim( $s ); |
130 |
131 |
131 /** |
132 /** |
132 * Filter the minimum number of characters required to fire a tag search via AJAX. |
133 * Filters the minimum number of characters required to fire a tag search via Ajax. |
133 * |
134 * |
134 * @since 4.0.0 |
135 * @since 4.0.0 |
135 * |
136 * |
136 * @param int $characters The minimum number of characters required. Default 2. |
137 * @param int $characters The minimum number of characters required. Default 2. |
137 * @param object $tax The taxonomy object. |
138 * @param WP_Taxonomy $tax The taxonomy object. |
138 * @param string $s The search term. |
139 * @param string $s The search term. |
139 */ |
140 */ |
140 $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s ); |
141 $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s ); |
141 |
142 |
142 /* |
143 /* |
143 * Require $term_search_min_chars chars for matching (default: 2) |
144 * Require $term_search_min_chars chars for matching (default: 2) |
169 |
170 |
170 if ( isset($_GET['test']) ) { |
171 if ( isset($_GET['test']) ) { |
171 header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' ); |
172 header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' ); |
172 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); |
173 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); |
173 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' ); |
174 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' ); |
174 header( 'Pragma: no-cache' ); |
|
175 header('Content-Type: application/javascript; charset=UTF-8'); |
175 header('Content-Type: application/javascript; charset=UTF-8'); |
176 $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP ); |
176 $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP ); |
177 $test_str = '"wpCompressionTest Lorem ipsum dolor sit amet consectetuer mollis sapien urna ut a. Eu nonummy condimentum fringilla tempor pretium platea vel nibh netus Maecenas. Hac molestie amet justo quis pellentesque est ultrices interdum nibh Morbi. Cras mattis pretium Phasellus ante ipsum ipsum ut sociis Suspendisse Lorem. Ante et non molestie. Porta urna Vestibulum egestas id congue nibh eu risus gravida sit. Ac augue auctor Ut et non a elit massa id sodales. Elit eu Nulla at nibh adipiscing mattis lacus mauris at tempus. Netus nibh quis suscipit nec feugiat eget sed lorem et urna. Pellentesque lacus at ut massa consectetuer ligula ut auctor semper Pellentesque. Ut metus massa nibh quam Curabitur molestie nec mauris congue. Volutpat molestie elit justo facilisis neque ac risus Ut nascetur tristique. Vitae sit lorem tellus et quis Phasellus lacus tincidunt nunc Fusce. Pharetra wisi Suspendisse mus sagittis libero lacinia Integer consequat ac Phasellus. Et urna ac cursus tortor aliquam Aliquam amet tellus volutpat Vestibulum. Justo interdum condimentum In augue congue tellus sollicitudin Quisque quis nibh."'; |
177 $test_str = '"wpCompressionTest Lorem ipsum dolor sit amet consectetuer mollis sapien urna ut a. Eu nonummy condimentum fringilla tempor pretium platea vel nibh netus Maecenas. Hac molestie amet justo quis pellentesque est ultrices interdum nibh Morbi. Cras mattis pretium Phasellus ante ipsum ipsum ut sociis Suspendisse Lorem. Ante et non molestie. Porta urna Vestibulum egestas id congue nibh eu risus gravida sit. Ac augue auctor Ut et non a elit massa id sodales. Elit eu Nulla at nibh adipiscing mattis lacus mauris at tempus. Netus nibh quis suscipit nec feugiat eget sed lorem et urna. Pellentesque lacus at ut massa consectetuer ligula ut auctor semper Pellentesque. Ut metus massa nibh quam Curabitur molestie nec mauris congue. Volutpat molestie elit justo facilisis neque ac risus Ut nascetur tristique. Vitae sit lorem tellus et quis Phasellus lacus tincidunt nunc Fusce. Pharetra wisi Suspendisse mus sagittis libero lacinia Integer consequat ac Phasellus. Et urna ac cursus tortor aliquam Aliquam amet tellus volutpat Vestibulum. Justo interdum condimentum In augue congue tellus sollicitudin Quisque quis nibh."'; |
178 |
178 |
179 if ( 1 == $_GET['test'] ) { |
179 if ( 1 == $_GET['test'] ) { |
192 wp_die( -1 ); |
192 wp_die( -1 ); |
193 } |
193 } |
194 echo $out; |
194 echo $out; |
195 wp_die(); |
195 wp_die(); |
196 } elseif ( 'no' == $_GET['test'] ) { |
196 } elseif ( 'no' == $_GET['test'] ) { |
197 check_ajax_referer( 'update_can_compress_scripts' ); |
|
197 update_site_option('can_compress_scripts', 0); |
198 update_site_option('can_compress_scripts', 0); |
198 } elseif ( 'yes' == $_GET['test'] ) { |
199 } elseif ( 'yes' == $_GET['test'] ) { |
200 check_ajax_referer( 'update_can_compress_scripts' ); |
|
199 update_site_option('can_compress_scripts', 1); |
201 update_site_option('can_compress_scripts', 1); |
200 } |
202 } |
201 } |
203 } |
202 |
204 |
203 wp_die( 0 ); |
205 wp_die( 0 ); |
224 |
226 |
225 /** |
227 /** |
226 * Ajax handler for oEmbed caching. |
228 * Ajax handler for oEmbed caching. |
227 * |
229 * |
228 * @since 3.1.0 |
230 * @since 3.1.0 |
231 * |
|
232 * @global WP_Embed $wp_embed |
|
229 */ |
233 */ |
230 function wp_ajax_oembed_cache() { |
234 function wp_ajax_oembed_cache() { |
231 $GLOBALS['wp_embed']->cache_oembed( $_GET['post'] ); |
235 $GLOBALS['wp_embed']->cache_oembed( $_GET['post'] ); |
232 wp_die( 0 ); |
236 wp_die( 0 ); |
233 } |
237 } |
240 function wp_ajax_autocomplete_user() { |
244 function wp_ajax_autocomplete_user() { |
241 if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) |
245 if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) |
242 wp_die( -1 ); |
246 wp_die( -1 ); |
243 |
247 |
244 /** This filter is documented in wp-admin/user-new.php */ |
248 /** This filter is documented in wp-admin/user-new.php */ |
245 if ( ! is_super_admin() && ! apply_filters( 'autocomplete_users_for_site_admins', false ) ) |
249 if ( ! current_user_can( 'manage_network_users' ) && ! apply_filters( 'autocomplete_users_for_site_admins', false ) ) |
246 wp_die( -1 ); |
250 wp_die( -1 ); |
247 |
251 |
248 $return = array(); |
252 $return = array(); |
249 |
253 |
250 // Check the type of request |
254 // Check the type of request |
282 ) ); |
286 ) ); |
283 |
287 |
284 foreach ( $users as $user ) { |
288 foreach ( $users as $user ) { |
285 $return[] = array( |
289 $return[] = array( |
286 /* translators: 1: user_login, 2: user_email */ |
290 /* translators: 1: user_login, 2: user_email */ |
287 'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ), |
291 'label' => sprintf( _x( '%1$s (%2$s)', 'user autocomplete result' ), $user->user_login, $user->user_email ), |
288 'value' => $user->$field, |
292 'value' => $user->$field, |
289 ); |
293 ); |
290 } |
294 } |
291 |
295 |
292 wp_die( wp_json_encode( $return ) ); |
296 wp_die( wp_json_encode( $return ) ); |
297 } |
|
298 |
|
299 /** |
|
300 * Handles AJAX requests for community events |
|
301 * |
|
302 * @since 4.8.0 |
|
303 */ |
|
304 function wp_ajax_get_community_events() { |
|
305 require_once( ABSPATH . 'wp-admin/includes/class-wp-community-events.php' ); |
|
306 |
|
307 check_ajax_referer( 'community_events' ); |
|
308 |
|
309 $search = isset( $_POST['location'] ) ? wp_unslash( $_POST['location'] ) : ''; |
|
310 $timezone = isset( $_POST['timezone'] ) ? wp_unslash( $_POST['timezone'] ) : ''; |
|
311 $user_id = get_current_user_id(); |
|
312 $saved_location = get_user_option( 'community-events-location', $user_id ); |
|
313 $events_client = new WP_Community_Events( $user_id, $saved_location ); |
|
314 $events = $events_client->get_events( $search, $timezone ); |
|
315 $ip_changed = false; |
|
316 |
|
317 if ( is_wp_error( $events ) ) { |
|
318 wp_send_json_error( array( |
|
319 'error' => $events->get_error_message(), |
|
320 ) ); |
|
321 } else { |
|
322 if ( empty( $saved_location['ip'] ) && ! empty( $events['location']['ip'] ) ) { |
|
323 $ip_changed = true; |
|
324 } elseif ( isset( $saved_location['ip'] ) && ! empty( $events['location']['ip'] ) && $saved_location['ip'] !== $events['location']['ip'] ) { |
|
325 $ip_changed = true; |
|
326 } |
|
327 |
|
328 /* |
|
329 * The location should only be updated when it changes. The API doesn't always return |
|
330 * a full location; sometimes it's missing the description or country. The location |
|
331 * that was saved during the initial request is known to be good and complete, though. |
|
332 * It should be left in tact until the user explicitly changes it (either by manually |
|
333 * searching for a new location, or by changing their IP address). |
|
334 * |
|
335 * If the location were updated with an incomplete response from the API, then it could |
|
336 * break assumptions that the UI makes (e.g., that there will always be a description |
|
337 * that corresponds to a latitude/longitude location). |
|
338 * |
|
339 * The location is stored network-wide, so that the user doesn't have to set it on each site. |
|
340 */ |
|
341 if ( $ip_changed || $search ) { |
|
342 update_user_option( $user_id, 'community-events-location', $events['location'], true ); |
|
343 } |
|
344 |
|
345 wp_send_json_success( $events ); |
|
346 } |
|
293 } |
347 } |
294 |
348 |
295 /** |
349 /** |
296 * Ajax handler for dashboard widgets. |
350 * Ajax handler for dashboard widgets. |
297 * |
351 * |
327 // |
381 // |
328 |
382 |
329 /** |
383 /** |
330 * Sends back current comment total and new page links if they need to be updated. |
384 * Sends back current comment total and new page links if they need to be updated. |
331 * |
385 * |
332 * Contrary to normal success AJAX response ("1"), die with time() on success. |
386 * Contrary to normal success Ajax response ("1"), die with time() on success. |
333 * |
387 * |
388 * @access private |
|
334 * @since 2.7.0 |
389 * @since 2.7.0 |
335 * |
390 * |
336 * @param int $comment_id |
391 * @param int $comment_id |
337 * @return die |
392 * @param int $delta |
338 */ |
393 */ |
339 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { |
394 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) { |
340 $total = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0; |
395 $total = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0; |
341 $per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0; |
396 $per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0; |
342 $page = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0; |
397 $page = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0; |
343 $url = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : ''; |
398 $url = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : ''; |
344 |
399 |
345 // JS didn't send us everything we need to know. Just die with success message |
400 // JS didn't send us everything we need to know. Just die with success message |
346 if ( !$total || !$per_page || !$page || !$url ) |
401 if ( ! $total || ! $per_page || ! $page || ! $url ) { |
347 wp_die( time() ); |
402 $time = time(); |
403 $comment = get_comment( $comment_id ); |
|
404 $comment_status = ''; |
|
405 $comment_link = ''; |
|
406 |
|
407 if ( $comment ) { |
|
408 $comment_status = $comment->comment_approved; |
|
409 } |
|
410 |
|
411 if ( 1 === (int) $comment_status ) { |
|
412 $comment_link = get_comment_link( $comment ); |
|
413 } |
|
414 |
|
415 $counts = wp_count_comments(); |
|
416 |
|
417 $x = new WP_Ajax_Response( array( |
|
418 'what' => 'comment', |
|
419 // Here for completeness - not used. |
|
420 'id' => $comment_id, |
|
421 'supplemental' => array( |
|
422 'status' => $comment_status, |
|
423 'postId' => $comment ? $comment->comment_post_ID : '', |
|
424 'time' => $time, |
|
425 'in_moderation' => $counts->moderated, |
|
426 'i18n_comments_text' => sprintf( |
|
427 _n( '%s Comment', '%s Comments', $counts->approved ), |
|
428 number_format_i18n( $counts->approved ) |
|
429 ), |
|
430 'i18n_moderation_text' => sprintf( |
|
431 _nx( '%s in moderation', '%s in moderation', $counts->moderated, 'comments' ), |
|
432 number_format_i18n( $counts->moderated ) |
|
433 ), |
|
434 'comment_link' => $comment_link, |
|
435 ) |
|
436 ) ); |
|
437 $x->send(); |
|
438 } |
|
348 |
439 |
349 $total += $delta; |
440 $total += $delta; |
350 if ( $total < 0 ) |
441 if ( $total < 0 ) |
351 $total = 0; |
442 $total = 0; |
352 |
443 |
353 // Only do the expensive stuff on a page-break, and about 1 other time per page |
444 // Only do the expensive stuff on a page-break, and about 1 other time per page |
354 if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) { |
445 if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) { |
355 $post_id = 0; |
446 $post_id = 0; |
356 $status = 'total_comments'; // What type of comment count are we looking for? |
447 // What type of comment count are we looking for? |
448 $status = 'all'; |
|
357 $parsed = parse_url( $url ); |
449 $parsed = parse_url( $url ); |
358 if ( isset( $parsed['query'] ) ) { |
450 if ( isset( $parsed['query'] ) ) { |
359 parse_str( $parsed['query'], $query_vars ); |
451 parse_str( $parsed['query'], $query_vars ); |
360 if ( !empty( $query_vars['comment_status'] ) ) |
452 if ( !empty( $query_vars['comment_status'] ) ) |
361 $status = $query_vars['comment_status']; |
453 $status = $query_vars['comment_status']; |
362 if ( !empty( $query_vars['p'] ) ) |
454 if ( !empty( $query_vars['p'] ) ) |
363 $post_id = (int) $query_vars['p']; |
455 $post_id = (int) $query_vars['p']; |
364 } |
456 if ( ! empty( $query_vars['comment_type'] ) ) |
365 |
457 $type = $query_vars['comment_type']; |
366 $comment_count = wp_count_comments($post_id); |
458 } |
367 |
459 |
368 // We're looking for a known type of comment count. |
460 if ( empty( $type ) ) { |
369 if ( isset( $comment_count->$status ) ) |
461 // Only use the comment count if not filtering by a comment_type. |
370 $total = $comment_count->$status; |
462 $comment_count = wp_count_comments($post_id); |
371 // Else use the decremented value from above. |
463 |
464 // We're looking for a known type of comment count. |
|
465 if ( isset( $comment_count->$status ) ) { |
|
466 $total = $comment_count->$status; |
|
467 } |
|
468 } |
|
469 // Else use the decremented value from above. |
|
372 } |
470 } |
373 |
471 |
374 // The time since the last comment count. |
472 // The time since the last comment count. |
375 $time = time(); |
473 $time = time(); |
474 $comment = get_comment( $comment_id ); |
|
376 |
475 |
377 $x = new WP_Ajax_Response( array( |
476 $x = new WP_Ajax_Response( array( |
378 'what' => 'comment', |
477 'what' => 'comment', |
379 // Here for completeness - not used. |
478 // Here for completeness - not used. |
380 'id' => $comment_id, |
479 'id' => $comment_id, |
381 'supplemental' => array( |
480 'supplemental' => array( |
481 'status' => $comment ? $comment->comment_approved : '', |
|
482 'postId' => $comment ? $comment->comment_post_ID : '', |
|
382 'total_items_i18n' => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ), |
483 'total_items_i18n' => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ), |
383 'total_pages' => ceil( $total / $per_page ), |
484 'total_pages' => ceil( $total / $per_page ), |
384 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ), |
485 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ), |
385 'total' => $total, |
486 'total' => $total, |
386 'time' => $time |
487 'time' => $time |
394 // |
495 // |
395 |
496 |
396 /** |
497 /** |
397 * Ajax handler for adding a hierarchical term. |
498 * Ajax handler for adding a hierarchical term. |
398 * |
499 * |
500 * @access private |
|
399 * @since 3.1.0 |
501 * @since 3.1.0 |
400 */ |
502 */ |
401 function _wp_ajax_add_hierarchical_term() { |
503 function _wp_ajax_add_hierarchical_term() { |
402 $action = $_POST['action']; |
504 $action = $_POST['action']; |
403 $taxonomy = get_taxonomy(substr($action, 4)); |
505 $taxonomy = get_taxonomy(substr($action, 4)); |
418 foreach ( $names as $cat_name ) { |
520 foreach ( $names as $cat_name ) { |
419 $cat_name = trim($cat_name); |
521 $cat_name = trim($cat_name); |
420 $category_nicename = sanitize_title($cat_name); |
522 $category_nicename = sanitize_title($cat_name); |
421 if ( '' === $category_nicename ) |
523 if ( '' === $category_nicename ) |
422 continue; |
524 continue; |
423 if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) ) |
525 |
424 $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) ); |
526 $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) ); |
425 if ( is_wp_error( $cat_id ) ) { |
527 if ( ! $cat_id || is_wp_error( $cat_id ) ) { |
426 continue; |
528 continue; |
427 } elseif ( is_array( $cat_id ) ) { |
529 } else { |
428 $cat_id = $cat_id['term_id']; |
530 $cat_id = $cat_id['term_id']; |
429 } |
531 } |
430 $checked_categories[] = $cat_id; |
532 $checked_categories[] = $cat_id; |
431 if ( $parent ) // Do these all at once in a second |
533 if ( $parent ) // Do these all at once in a second |
432 continue; |
534 continue; |
535 |
|
433 ob_start(); |
536 ob_start(); |
434 wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids )); |
537 |
435 $data = ob_get_contents(); |
538 wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids )); |
436 ob_end_clean(); |
539 |
540 $data = ob_get_clean(); |
|
541 |
|
437 $add = array( |
542 $add = array( |
438 'what' => $taxonomy->name, |
543 'what' => $taxonomy->name, |
439 'id' => $cat_id, |
544 'id' => $cat_id, |
440 'data' => str_replace( array("\n", "\t"), '', $data), |
545 'data' => str_replace( array("\n", "\t"), '', $data), |
441 'position' => -1 |
546 'position' => -1 |
452 break; |
557 break; |
453 $term_id = $parent->term_id; |
558 $term_id = $parent->term_id; |
454 } |
559 } |
455 |
560 |
456 ob_start(); |
561 ob_start(); |
457 wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids)); |
562 |
458 $data = ob_get_contents(); |
563 wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids)); |
459 ob_end_clean(); |
564 |
565 $data = ob_get_clean(); |
|
566 |
|
460 $add = array( |
567 $add = array( |
461 'what' => $taxonomy->name, |
568 'what' => $taxonomy->name, |
462 'id' => $term_id, |
569 'id' => $term_id, |
463 'data' => str_replace( array("\n", "\t"), '', $data), |
570 'data' => str_replace( array("\n", "\t"), '', $data), |
464 'position' => -1 |
571 'position' => -1 |
465 ); |
572 ); |
466 } |
573 } |
467 |
574 |
468 ob_start(); |
575 ob_start(); |
469 wp_dropdown_categories( array( |
576 |
470 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name', |
577 wp_dropdown_categories( array( |
471 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —' |
578 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name', |
472 ) ); |
579 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —' |
473 $sup = ob_get_contents(); |
580 ) ); |
474 ob_end_clean(); |
581 |
582 $sup = ob_get_clean(); |
|
583 |
|
475 $add['supplemental'] = array( 'newcat_parent' => $sup ); |
584 $add['supplemental'] = array( 'newcat_parent' => $sup ); |
476 |
585 |
477 $x = new WP_Ajax_Response( $add ); |
586 $x = new WP_Ajax_Response( $add ); |
478 $x->send(); |
587 $x->send(); |
479 } |
588 } |
490 wp_die( time() ); |
599 wp_die( time() ); |
491 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) |
600 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) |
492 wp_die( -1 ); |
601 wp_die( -1 ); |
493 |
602 |
494 check_ajax_referer( "delete-comment_$id" ); |
603 check_ajax_referer( "delete-comment_$id" ); |
495 $status = wp_get_comment_status( $comment->comment_ID ); |
604 $status = wp_get_comment_status( $comment ); |
496 |
605 |
497 $delta = -1; |
606 $delta = -1; |
498 if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) { |
607 if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) { |
499 if ( 'trash' == $status ) |
608 if ( 'trash' == $status ) |
500 wp_die( time() ); |
609 wp_die( time() ); |
501 $r = wp_trash_comment( $comment->comment_ID ); |
610 $r = wp_trash_comment( $comment ); |
502 } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) { |
611 } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) { |
503 if ( 'trash' != $status ) |
612 if ( 'trash' != $status ) |
504 wp_die( time() ); |
613 wp_die( time() ); |
505 $r = wp_untrash_comment( $comment->comment_ID ); |
614 $r = wp_untrash_comment( $comment ); |
506 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash |
615 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash |
507 $delta = 1; |
616 $delta = 1; |
508 } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) { |
617 } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) { |
509 if ( 'spam' == $status ) |
618 if ( 'spam' == $status ) |
510 wp_die( time() ); |
619 wp_die( time() ); |
511 $r = wp_spam_comment( $comment->comment_ID ); |
620 $r = wp_spam_comment( $comment ); |
512 } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) { |
621 } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) { |
513 if ( 'spam' != $status ) |
622 if ( 'spam' != $status ) |
514 wp_die( time() ); |
623 wp_die( time() ); |
515 $r = wp_unspam_comment( $comment->comment_ID ); |
624 $r = wp_unspam_comment( $comment ); |
516 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam |
625 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam |
517 $delta = 1; |
626 $delta = 1; |
518 } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) { |
627 } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) { |
519 $r = wp_delete_comment( $comment->comment_ID ); |
628 $r = wp_delete_comment( $comment ); |
520 } else { |
629 } else { |
521 wp_die( -1 ); |
630 wp_die( -1 ); |
522 } |
631 } |
523 |
632 |
524 if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts |
633 if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts |
533 */ |
642 */ |
534 function wp_ajax_delete_tag() { |
643 function wp_ajax_delete_tag() { |
535 $tag_id = (int) $_POST['tag_ID']; |
644 $tag_id = (int) $_POST['tag_ID']; |
536 check_ajax_referer( "delete-tag_$tag_id" ); |
645 check_ajax_referer( "delete-tag_$tag_id" ); |
537 |
646 |
647 if ( ! current_user_can( 'delete_term', $tag_id ) ) { |
|
648 wp_die( -1 ); |
|
649 } |
|
650 |
|
538 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; |
651 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; |
539 $tax = get_taxonomy($taxonomy); |
|
540 |
|
541 if ( !current_user_can( $tax->cap->delete_terms ) ) |
|
542 wp_die( -1 ); |
|
543 |
|
544 $tag = get_term( $tag_id, $taxonomy ); |
652 $tag = get_term( $tag_id, $taxonomy ); |
545 if ( !$tag || is_wp_error( $tag ) ) |
653 if ( !$tag || is_wp_error( $tag ) ) |
546 wp_die( 1 ); |
654 wp_die( 1 ); |
547 |
655 |
548 if ( wp_delete_term($tag_id, $taxonomy)) |
656 if ( wp_delete_term($tag_id, $taxonomy)) |
658 if ( empty( $action ) ) |
766 if ( empty( $action ) ) |
659 $action = 'untrash-post'; |
767 $action = 'untrash-post'; |
660 wp_ajax_trash_post( $action ); |
768 wp_ajax_trash_post( $action ); |
661 } |
769 } |
662 |
770 |
771 /** |
|
772 * @since 3.1.0 |
|
773 * |
|
774 * @param string $action |
|
775 */ |
|
663 function wp_ajax_delete_page( $action ) { |
776 function wp_ajax_delete_page( $action ) { |
664 if ( empty( $action ) ) |
777 if ( empty( $action ) ) |
665 $action = 'delete-page'; |
778 $action = 'delete-page'; |
666 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; |
779 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0; |
667 |
780 |
695 } |
808 } |
696 |
809 |
697 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) ) |
810 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) ) |
698 wp_die( -1 ); |
811 wp_die( -1 ); |
699 |
812 |
700 $current = wp_get_comment_status( $comment->comment_ID ); |
813 $current = wp_get_comment_status( $comment ); |
701 if ( isset( $_POST['new'] ) && $_POST['new'] == $current ) |
814 if ( isset( $_POST['new'] ) && $_POST['new'] == $current ) |
702 wp_die( time() ); |
815 wp_die( time() ); |
703 |
816 |
704 check_ajax_referer( "approve-comment_$id" ); |
817 check_ajax_referer( "approve-comment_$id" ); |
705 if ( in_array( $current, array( 'unapproved', 'spam' ) ) ) |
818 if ( in_array( $current, array( 'unapproved', 'spam' ) ) ) { |
706 $result = wp_set_comment_status( $comment->comment_ID, 'approve', true ); |
819 $result = wp_set_comment_status( $comment, 'approve', true ); |
707 else |
820 } else { |
708 $result = wp_set_comment_status( $comment->comment_ID, 'hold', true ); |
821 $result = wp_set_comment_status( $comment, 'hold', true ); |
822 } |
|
709 |
823 |
710 if ( is_wp_error($result) ) { |
824 if ( is_wp_error($result) ) { |
711 $x = new WP_Ajax_Response( array( |
825 $x = new WP_Ajax_Response( array( |
712 'what' => 'comment', |
826 'what' => 'comment', |
713 'id' => $result |
827 'id' => $result |
719 _wp_ajax_delete_comment_response( $comment->comment_ID ); |
833 _wp_ajax_delete_comment_response( $comment->comment_ID ); |
720 wp_die( 0 ); |
834 wp_die( 0 ); |
721 } |
835 } |
722 |
836 |
723 /** |
837 /** |
724 * Ajax handler for deleting a link category. |
838 * Ajax handler for adding a link category. |
725 * |
839 * |
726 * @since 3.1.0 |
840 * @since 3.1.0 |
727 * |
841 * |
728 * @param string $action Action to perform. |
842 * @param string $action Action to perform. |
729 */ |
843 */ |
730 function wp_ajax_add_link_category( $action ) { |
844 function wp_ajax_add_link_category( $action ) { |
731 if ( empty( $action ) ) |
845 if ( empty( $action ) ) |
732 $action = 'add-link-category'; |
846 $action = 'add-link-category'; |
733 check_ajax_referer( $action ); |
847 check_ajax_referer( $action ); |
734 if ( !current_user_can( 'manage_categories' ) ) |
848 $tax = get_taxonomy( 'link_category' ); |
849 if ( ! current_user_can( $tax->cap->manage_terms ) ) { |
|
735 wp_die( -1 ); |
850 wp_die( -1 ); |
851 } |
|
736 $names = explode(',', wp_unslash( $_POST['newcat'] ) ); |
852 $names = explode(',', wp_unslash( $_POST['newcat'] ) ); |
737 $x = new WP_Ajax_Response(); |
853 $x = new WP_Ajax_Response(); |
738 foreach ( $names as $cat_name ) { |
854 foreach ( $names as $cat_name ) { |
739 $cat_name = trim($cat_name); |
855 $cat_name = trim($cat_name); |
740 $slug = sanitize_title($cat_name); |
856 $slug = sanitize_title($cat_name); |
741 if ( '' === $slug ) |
857 if ( '' === $slug ) |
742 continue; |
858 continue; |
743 if ( !$cat_id = term_exists( $cat_name, 'link_category' ) ) |
859 |
744 $cat_id = wp_insert_term( $cat_name, 'link_category' ); |
860 $cat_id = wp_insert_term( $cat_name, 'link_category' ); |
745 if ( is_wp_error( $cat_id ) ) { |
861 if ( ! $cat_id || is_wp_error( $cat_id ) ) { |
746 continue; |
862 continue; |
747 } elseif ( is_array( $cat_id ) ) { |
863 } else { |
748 $cat_id = $cat_id['term_id']; |
864 $cat_id = $cat_id['term_id']; |
749 } |
865 } |
750 $cat_name = esc_html( $cat_name ); |
866 $cat_name = esc_html( $cat_name ); |
751 $x->add( array( |
867 $x->add( array( |
752 'what' => 'link-category', |
868 'what' => 'link-category', |
762 * Ajax handler to add a tag. |
878 * Ajax handler to add a tag. |
763 * |
879 * |
764 * @since 3.1.0 |
880 * @since 3.1.0 |
765 */ |
881 */ |
766 function wp_ajax_add_tag() { |
882 function wp_ajax_add_tag() { |
767 global $wp_list_table; |
|
768 |
|
769 check_ajax_referer( 'add-tag', '_wpnonce_add-tag' ); |
883 check_ajax_referer( 'add-tag', '_wpnonce_add-tag' ); |
770 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; |
884 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag'; |
771 $tax = get_taxonomy($taxonomy); |
885 $tax = get_taxonomy($taxonomy); |
772 |
886 |
773 if ( !current_user_can( $tax->cap->edit_terms ) ) |
887 if ( !current_user_can( $tax->cap->edit_terms ) ) |
804 $parents = ob_get_clean(); |
918 $parents = ob_get_clean(); |
805 |
919 |
806 $x->add( array( |
920 $x->add( array( |
807 'what' => 'taxonomy', |
921 'what' => 'taxonomy', |
808 'supplemental' => compact('parents', 'noparents') |
922 'supplemental' => compact('parents', 'noparents') |
809 ) ); |
923 ) ); |
810 $x->add( array( |
924 $x->add( array( |
811 'what' => 'term', |
925 'what' => 'term', |
812 'position' => $level, |
926 'position' => $level, |
813 'supplemental' => (array) $tag |
927 'supplemental' => (array) $tag |
814 ) ); |
928 ) ); |
815 $x->send(); |
929 $x->send(); |
816 } |
930 } |
817 |
931 |
818 /** |
932 /** |
819 * Ajax handler for getting a tagcloud. |
933 * Ajax handler for getting a tagcloud. |
847 $tags[ $key ]->link = '#'; |
961 $tags[ $key ]->link = '#'; |
848 $tags[ $key ]->id = $tag->term_id; |
962 $tags[ $key ]->id = $tag->term_id; |
849 } |
963 } |
850 |
964 |
851 // We need raw tag names here, so don't filter the output |
965 // We need raw tag names here, so don't filter the output |
852 $return = wp_generate_tag_cloud( $tags, array('filter' => 0) ); |
966 $return = wp_generate_tag_cloud( $tags, array( 'filter' => 0, 'format' => 'list' ) ); |
853 |
967 |
854 if ( empty($return) ) |
968 if ( empty($return) ) |
855 wp_die( 0 ); |
969 wp_die( 0 ); |
856 |
970 |
857 echo $return; |
971 echo $return; |
862 /** |
976 /** |
863 * Ajax handler for getting comments. |
977 * Ajax handler for getting comments. |
864 * |
978 * |
865 * @since 3.1.0 |
979 * @since 3.1.0 |
866 * |
980 * |
981 * @global int $post_id |
|
982 * |
|
867 * @param string $action Action to perform. |
983 * @param string $action Action to perform. |
868 */ |
984 */ |
869 function wp_ajax_get_comments( $action ) { |
985 function wp_ajax_get_comments( $action ) { |
870 global $wp_list_table, $post_id; |
986 global $post_id; |
871 if ( empty( $action ) ) |
987 if ( empty( $action ) ) { |
872 $action = 'get-comments'; |
988 $action = 'get-comments'; |
873 |
989 } |
874 check_ajax_referer( $action ); |
990 check_ajax_referer( $action ); |
875 |
991 |
876 if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) { |
992 if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) { |
877 $id = absint( $_REQUEST['p'] ); |
993 $id = absint( $_REQUEST['p'] ); |
878 if ( ! empty( $id ) ) |
994 if ( ! empty( $id ) ) { |
879 $post_id = $id; |
995 $post_id = $id; |
880 } |
996 } |
881 |
997 } |
882 if ( empty( $post_id ) ) |
998 |
999 if ( empty( $post_id ) ) { |
|
883 wp_die( -1 ); |
1000 wp_die( -1 ); |
1001 } |
|
884 |
1002 |
885 $wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) ); |
1003 $wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) ); |
886 |
1004 |
887 if ( ! current_user_can( 'edit_post', $post_id ) ) |
1005 if ( ! current_user_can( 'edit_post', $post_id ) ) { |
888 wp_die( -1 ); |
1006 wp_die( -1 ); |
1007 } |
|
889 |
1008 |
890 $wp_list_table->prepare_items(); |
1009 $wp_list_table->prepare_items(); |
891 |
1010 |
892 if ( !$wp_list_table->has_items() ) |
1011 if ( ! $wp_list_table->has_items() ) { |
893 wp_die( 1 ); |
1012 wp_die( 1 ); |
1013 } |
|
894 |
1014 |
895 $x = new WP_Ajax_Response(); |
1015 $x = new WP_Ajax_Response(); |
896 ob_start(); |
1016 ob_start(); |
897 foreach ( $wp_list_table->items as $comment ) { |
1017 foreach ( $wp_list_table->items as $comment ) { |
898 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) |
1018 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && 0 === $comment->comment_approved ) |
899 continue; |
1019 continue; |
900 get_comment( $comment ); |
1020 get_comment( $comment ); |
901 $wp_list_table->single_row( $comment ); |
1021 $wp_list_table->single_row( $comment ); |
902 } |
1022 } |
903 $comment_list_item = ob_get_contents(); |
1023 $comment_list_item = ob_get_clean(); |
904 ob_end_clean(); |
|
905 |
1024 |
906 $x->add( array( |
1025 $x->add( array( |
907 'what' => 'comments', |
1026 'what' => 'comments', |
908 'data' => $comment_list_item |
1027 'data' => $comment_list_item |
909 ) ); |
1028 ) ); |
916 * @since 3.1.0 |
1035 * @since 3.1.0 |
917 * |
1036 * |
918 * @param string $action Action to perform. |
1037 * @param string $action Action to perform. |
919 */ |
1038 */ |
920 function wp_ajax_replyto_comment( $action ) { |
1039 function wp_ajax_replyto_comment( $action ) { |
921 global $wp_list_table; |
|
922 if ( empty( $action ) ) |
1040 if ( empty( $action ) ) |
923 $action = 'replyto-comment'; |
1041 $action = 'replyto-comment'; |
924 |
1042 |
925 check_ajax_referer( $action, '_ajax_nonce-replyto-comment' ); |
1043 check_ajax_referer( $action, '_ajax_nonce-replyto-comment' ); |
926 |
1044 |
970 // Automatically approve parent comment. |
1088 // Automatically approve parent comment. |
971 if ( !empty($_POST['approve_parent']) ) { |
1089 if ( !empty($_POST['approve_parent']) ) { |
972 $parent = get_comment( $comment_parent ); |
1090 $parent = get_comment( $comment_parent ); |
973 |
1091 |
974 if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) { |
1092 if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) { |
975 if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) ) |
1093 if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) { |
1094 wp_die( -1 ); |
|
1095 } |
|
1096 |
|
1097 if ( wp_set_comment_status( $parent, 'approve' ) ) |
|
976 $comment_auto_approved = true; |
1098 $comment_auto_approved = true; |
977 } |
1099 } |
978 } |
1100 } |
979 |
1101 |
980 $comment_id = wp_new_comment( $commentdata ); |
1102 $comment_id = wp_new_comment( $commentdata ); |
1103 |
|
1104 if ( is_wp_error( $comment_id ) ) { |
|
1105 wp_die( $comment_id->get_error_message() ); |
|
1106 } |
|
1107 |
|
981 $comment = get_comment($comment_id); |
1108 $comment = get_comment($comment_id); |
982 if ( ! $comment ) wp_die( 1 ); |
1109 if ( ! $comment ) wp_die( 1 ); |
983 |
1110 |
984 $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1'; |
1111 $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1'; |
985 |
1112 |
1002 'id' => $comment->comment_ID, |
1129 'id' => $comment->comment_ID, |
1003 'data' => $comment_list_item, |
1130 'data' => $comment_list_item, |
1004 'position' => $position |
1131 'position' => $position |
1005 ); |
1132 ); |
1006 |
1133 |
1007 if ( $comment_auto_approved ) |
1134 $counts = wp_count_comments(); |
1008 $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID ); |
1135 $response['supplemental'] = array( |
1136 'in_moderation' => $counts->moderated, |
|
1137 'i18n_comments_text' => sprintf( |
|
1138 _n( '%s Comment', '%s Comments', $counts->approved ), |
|
1139 number_format_i18n( $counts->approved ) |
|
1140 ), |
|
1141 'i18n_moderation_text' => sprintf( |
|
1142 _nx( '%s in moderation', '%s in moderation', $counts->moderated, 'comments' ), |
|
1143 number_format_i18n( $counts->moderated ) |
|
1144 ) |
|
1145 ); |
|
1146 |
|
1147 if ( $comment_auto_approved ) { |
|
1148 $response['supplemental']['parent_approved'] = $parent->comment_ID; |
|
1149 $response['supplemental']['parent_post_id'] = $parent->comment_post_ID; |
|
1150 } |
|
1009 |
1151 |
1010 $x = new WP_Ajax_Response(); |
1152 $x = new WP_Ajax_Response(); |
1011 $x->add( $response ); |
1153 $x->add( $response ); |
1012 $x->send(); |
1154 $x->send(); |
1013 } |
1155 } |
1016 * Ajax handler for editing a comment. |
1158 * Ajax handler for editing a comment. |
1017 * |
1159 * |
1018 * @since 3.1.0 |
1160 * @since 3.1.0 |
1019 */ |
1161 */ |
1020 function wp_ajax_edit_comment() { |
1162 function wp_ajax_edit_comment() { |
1021 global $wp_list_table; |
|
1022 |
|
1023 check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ); |
1163 check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ); |
1024 |
1164 |
1025 $comment_id = (int) $_POST['comment_ID']; |
1165 $comment_id = (int) $_POST['comment_ID']; |
1026 if ( ! current_user_can( 'edit_comment', $comment_id ) ) |
1166 if ( ! current_user_can( 'edit_comment', $comment_id ) ) |
1027 wp_die( -1 ); |
1167 wp_die( -1 ); |
1083 switch( $menu_item_data['menu-item-type'] ) { |
1223 switch( $menu_item_data['menu-item-type'] ) { |
1084 case 'post_type' : |
1224 case 'post_type' : |
1085 $_object = get_post( $menu_item_data['menu-item-object-id'] ); |
1225 $_object = get_post( $menu_item_data['menu-item-object-id'] ); |
1086 break; |
1226 break; |
1087 |
1227 |
1228 case 'post_type_archive' : |
|
1229 $_object = get_post_type_object( $menu_item_data['menu-item-object'] ); |
|
1230 break; |
|
1231 |
|
1088 case 'taxonomy' : |
1232 case 'taxonomy' : |
1089 $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] ); |
1233 $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] ); |
1090 break; |
1234 break; |
1091 } |
1235 } |
1092 |
1236 |
1151 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) ) |
1295 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) ) |
1152 wp_die( 1 ); |
1296 wp_die( 1 ); |
1153 |
1297 |
1154 // If the post is an autodraft, save the post as a draft and then attempt to save the meta. |
1298 // If the post is an autodraft, save the post as a draft and then attempt to save the meta. |
1155 if ( $post->post_status == 'auto-draft' ) { |
1299 if ( $post->post_status == 'auto-draft' ) { |
1156 $save_POST = $_POST; // Backup $_POST |
1300 $post_data = array(); |
1157 $_POST = array(); // Make it empty for edit_post() |
1301 $post_data['action'] = 'draft'; // Warning fix |
1158 $_POST['action'] = 'draft'; // Warning fix |
1302 $post_data['post_ID'] = $pid; |
1159 $_POST['post_ID'] = $pid; |
1303 $post_data['post_type'] = $post->post_type; |
1160 $_POST['post_type'] = $post->post_type; |
1304 $post_data['post_status'] = 'draft'; |
1161 $_POST['post_status'] = 'draft'; |
|
1162 $now = current_time('timestamp', 1); |
1305 $now = current_time('timestamp', 1); |
1163 $_POST['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( get_option( 'date_format' ), $now ), date( get_option( 'time_format' ), $now ) ); |
1306 /* translators: 1: Post creation date, 2: Post creation time */ |
1164 |
1307 $post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( __( 'F j, Y' ), $now ), date( __( 'g:i a' ), $now ) ); |
1165 if ( $pid = edit_post() ) { |
1308 |
1309 $pid = edit_post( $post_data ); |
|
1310 if ( $pid ) { |
|
1166 if ( is_wp_error( $pid ) ) { |
1311 if ( is_wp_error( $pid ) ) { |
1167 $x = new WP_Ajax_Response( array( |
1312 $x = new WP_Ajax_Response( array( |
1168 'what' => 'meta', |
1313 'what' => 'meta', |
1169 'data' => $pid |
1314 'data' => $pid |
1170 ) ); |
1315 ) ); |
1171 $x->send(); |
1316 $x->send(); |
1172 } |
1317 } |
1173 $_POST = $save_POST; // Now we can restore original $_POST again |
1318 |
1174 if ( !$mid = add_meta( $pid ) ) |
1319 if ( !$mid = add_meta( $pid ) ) |
1175 wp_die( __( 'Please provide a custom field value.' ) ); |
1320 wp_die( __( 'Please provide a custom field value.' ) ); |
1176 } else { |
1321 } else { |
1177 wp_die( 0 ); |
1322 wp_die( 0 ); |
1178 } |
1323 } |
1230 * @since 3.1.0 |
1375 * @since 3.1.0 |
1231 * |
1376 * |
1232 * @param string $action Action to perform. |
1377 * @param string $action Action to perform. |
1233 */ |
1378 */ |
1234 function wp_ajax_add_user( $action ) { |
1379 function wp_ajax_add_user( $action ) { |
1235 global $wp_list_table; |
1380 if ( empty( $action ) ) { |
1236 if ( empty( $action ) ) |
|
1237 $action = 'add-user'; |
1381 $action = 'add-user'; |
1382 } |
|
1238 |
1383 |
1239 check_ajax_referer( $action ); |
1384 check_ajax_referer( $action ); |
1240 if ( ! current_user_can('create_users') ) |
1385 if ( ! current_user_can('create_users') ) |
1241 wp_die( -1 ); |
1386 wp_die( -1 ); |
1242 if ( ! $user_id = edit_user() ) { |
1387 if ( ! $user_id = edit_user() ) { |
1257 $x = new WP_Ajax_Response( array( |
1402 $x = new WP_Ajax_Response( array( |
1258 'what' => 'user', |
1403 'what' => 'user', |
1259 'id' => $user_id, |
1404 'id' => $user_id, |
1260 'data' => $wp_list_table->single_row( $user_object, '', $role ), |
1405 'data' => $wp_list_table->single_row( $user_object, '', $role ), |
1261 'supplemental' => array( |
1406 'supplemental' => array( |
1262 'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login), |
1407 'show-link' => sprintf( |
1408 /* translators: %s: the new user */ |
|
1409 __( 'User %s added' ), |
|
1410 '<a href="#user-' . $user_id . '">' . $user_object->user_login . '</a>' |
|
1411 ), |
|
1263 'role' => $role, |
1412 'role' => $role, |
1264 ) |
1413 ) |
1265 ) ); |
1414 ) ); |
1266 $x->send(); |
1415 $x->send(); |
1267 } |
1416 } |
1303 * |
1452 * |
1304 * @since 3.1.0 |
1453 * @since 3.1.0 |
1305 */ |
1454 */ |
1306 function wp_ajax_hidden_columns() { |
1455 function wp_ajax_hidden_columns() { |
1307 check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' ); |
1456 check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' ); |
1308 $hidden = explode( ',', isset( $_POST['hidden'] ) ? $_POST['hidden'] : '' ); |
|
1309 $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; |
1457 $page = isset( $_POST['page'] ) ? $_POST['page'] : ''; |
1310 |
1458 |
1311 if ( $page != sanitize_key( $page ) ) |
1459 if ( $page != sanitize_key( $page ) ) |
1312 wp_die( 0 ); |
1460 wp_die( 0 ); |
1313 |
1461 |
1314 if ( ! $user = wp_get_current_user() ) |
1462 if ( ! $user = wp_get_current_user() ) |
1315 wp_die( -1 ); |
1463 wp_die( -1 ); |
1316 |
1464 |
1317 if ( is_array($hidden) ) |
1465 $hidden = ! empty( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array(); |
1318 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true); |
1466 update_user_option( $user->ID, "manage{$page}columnshidden", $hidden, true ); |
1319 |
1467 |
1320 wp_die( 1 ); |
1468 wp_die( 1 ); |
1321 } |
1469 } |
1322 |
1470 |
1323 /** |
1471 /** |
1330 |
1478 |
1331 if ( ! current_user_can( 'edit_theme_options' ) ) |
1479 if ( ! current_user_can( 'edit_theme_options' ) ) |
1332 wp_die( -1 ); |
1480 wp_die( -1 ); |
1333 |
1481 |
1334 update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 ); |
1482 update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 ); |
1483 |
|
1484 wp_die( 1 ); |
|
1485 } |
|
1486 |
|
1487 /** |
|
1488 * Ajax handler for updating whether to display the Try Gutenberg panel. |
|
1489 * |
|
1490 * @since 4.9.8 |
|
1491 */ |
|
1492 function wp_ajax_update_try_gutenberg_panel() { |
|
1493 check_ajax_referer( 'try-gutenberg-panel-nonce', 'trygutenbergpanelnonce' ); |
|
1494 |
|
1495 update_user_meta( get_current_user_id(), 'show_try_gutenberg_panel', empty( $_POST['visible'] ) ? 0 : 1 ); |
|
1335 |
1496 |
1336 wp_die( 1 ); |
1497 wp_die( 1 ); |
1337 } |
1498 } |
1338 |
1499 |
1339 /** |
1500 /** |
1392 function wp_ajax_wp_link_ajax() { |
1553 function wp_ajax_wp_link_ajax() { |
1393 check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' ); |
1554 check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' ); |
1394 |
1555 |
1395 $args = array(); |
1556 $args = array(); |
1396 |
1557 |
1397 if ( isset( $_POST['search'] ) ) |
1558 if ( isset( $_POST['search'] ) ) { |
1398 $args['s'] = wp_unslash( $_POST['search'] ); |
1559 $args['s'] = wp_unslash( $_POST['search'] ); |
1560 } |
|
1561 |
|
1562 if ( isset( $_POST['term'] ) ) { |
|
1563 $args['s'] = wp_unslash( $_POST['term'] ); |
|
1564 } |
|
1565 |
|
1399 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; |
1566 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1; |
1400 |
1567 |
1401 require(ABSPATH . WPINC . '/class-wp-editor.php'); |
1568 if ( ! class_exists( '_WP_Editors', false ) ) { |
1569 require( ABSPATH . WPINC . '/class-wp-editor.php' ); |
|
1570 } |
|
1571 |
|
1402 $results = _WP_Editors::wp_link_query( $args ); |
1572 $results = _WP_Editors::wp_link_query( $args ); |
1403 |
1573 |
1404 if ( ! isset( $results ) ) |
1574 if ( ! isset( $results ) ) |
1405 wp_die( 0 ); |
1575 wp_die( 0 ); |
1406 |
1576 |
1477 * @since 3.1.0 |
1647 * @since 3.1.0 |
1478 */ |
1648 */ |
1479 function wp_ajax_get_permalink() { |
1649 function wp_ajax_get_permalink() { |
1480 check_ajax_referer( 'getpermalink', 'getpermalinknonce' ); |
1650 check_ajax_referer( 'getpermalink', 'getpermalinknonce' ); |
1481 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; |
1651 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0; |
1482 wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) ); |
1652 wp_die( get_preview_post_link( $post_id ) ); |
1483 } |
1653 } |
1484 |
1654 |
1485 /** |
1655 /** |
1486 * Ajax handler to retrieve a sample permalink. |
1656 * Ajax handler to retrieve a sample permalink. |
1487 * |
1657 * |
1497 |
1667 |
1498 /** |
1668 /** |
1499 * Ajax handler for Quick Edit saving a post from a list table. |
1669 * Ajax handler for Quick Edit saving a post from a list table. |
1500 * |
1670 * |
1501 * @since 3.1.0 |
1671 * @since 3.1.0 |
1672 * |
|
1673 * @global string $mode List table view mode. |
|
1502 */ |
1674 */ |
1503 function wp_ajax_inline_save() { |
1675 function wp_ajax_inline_save() { |
1504 global $wp_list_table; |
1676 global $mode; |
1505 |
1677 |
1506 check_ajax_referer( 'inlineeditnonce', '_inline_edit' ); |
1678 check_ajax_referer( 'inlineeditnonce', '_inline_edit' ); |
1507 |
1679 |
1508 if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) ) |
1680 if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) ) |
1509 wp_die(); |
1681 wp_die(); |
1510 |
1682 |
1511 if ( 'page' == $_POST['post_type'] ) { |
1683 if ( 'page' == $_POST['post_type'] ) { |
1512 if ( ! current_user_can( 'edit_page', $post_ID ) ) |
1684 if ( ! current_user_can( 'edit_page', $post_ID ) ) |
1513 wp_die( __( 'You are not allowed to edit this page.' ) ); |
1685 wp_die( __( 'Sorry, you are not allowed to edit this page.' ) ); |
1514 } else { |
1686 } else { |
1515 if ( ! current_user_can( 'edit_post', $post_ID ) ) |
1687 if ( ! current_user_can( 'edit_post', $post_ID ) ) |
1516 wp_die( __( 'You are not allowed to edit this post.' ) ); |
1688 wp_die( __( 'Sorry, you are not allowed to edit this post.' ) ); |
1517 } |
1689 } |
1518 |
1690 |
1519 if ( $last = wp_check_post_lock( $post_ID ) ) { |
1691 if ( $last = wp_check_post_lock( $post_ID ) ) { |
1520 $last_user = get_userdata( $last ); |
1692 $last_user = get_userdata( $last ); |
1521 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' ); |
1693 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' ); |
1538 |
1710 |
1539 if ( isset($data['post_parent']) ) |
1711 if ( isset($data['post_parent']) ) |
1540 $data['parent_id'] = $data['post_parent']; |
1712 $data['parent_id'] = $data['post_parent']; |
1541 |
1713 |
1542 // Status. |
1714 // Status. |
1543 if ( isset($data['keep_private']) && 'private' == $data['keep_private'] ) |
1715 if ( isset( $data['keep_private'] ) && 'private' == $data['keep_private'] ) { |
1716 $data['visibility'] = 'private'; |
|
1544 $data['post_status'] = 'private'; |
1717 $data['post_status'] = 'private'; |
1545 else |
1718 } else { |
1546 $data['post_status'] = $data['_status']; |
1719 $data['post_status'] = $data['_status']; |
1720 } |
|
1547 |
1721 |
1548 if ( empty($data['comment_status']) ) |
1722 if ( empty($data['comment_status']) ) |
1549 $data['comment_status'] = 'closed'; |
1723 $data['comment_status'] = 'closed'; |
1550 if ( empty($data['ping_status']) ) |
1724 if ( empty($data['ping_status']) ) |
1551 $data['ping_status'] = 'closed'; |
1725 $data['ping_status'] = 'closed'; |
1570 // Update the post. |
1744 // Update the post. |
1571 edit_post(); |
1745 edit_post(); |
1572 |
1746 |
1573 $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) ); |
1747 $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) ); |
1574 |
1748 |
1749 $mode = $_POST['post_view'] === 'excerpt' ? 'excerpt' : 'list'; |
|
1750 |
|
1575 $level = 0; |
1751 $level = 0; |
1576 $request_post = array( get_post( $_POST['post_ID'] ) ); |
1752 if ( is_post_type_hierarchical( $wp_list_table->screen->post_type ) ) { |
1577 $parent = $request_post[0]->post_parent; |
1753 $request_post = array( get_post( $_POST['post_ID'] ) ); |
1578 |
1754 $parent = $request_post[0]->post_parent; |
1579 while ( $parent > 0 ) { |
1755 |
1580 $parent_post = get_post( $parent ); |
1756 while ( $parent > 0 ) { |
1581 $parent = $parent_post->post_parent; |
1757 $parent_post = get_post( $parent ); |
1582 $level++; |
1758 $parent = $parent_post->post_parent; |
1759 $level++; |
|
1760 } |
|
1583 } |
1761 } |
1584 |
1762 |
1585 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level ); |
1763 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level ); |
1586 |
1764 |
1587 wp_die(); |
1765 wp_die(); |
1591 * Ajax handler for quick edit saving for a term. |
1769 * Ajax handler for quick edit saving for a term. |
1592 * |
1770 * |
1593 * @since 3.1.0 |
1771 * @since 3.1.0 |
1594 */ |
1772 */ |
1595 function wp_ajax_inline_save_tax() { |
1773 function wp_ajax_inline_save_tax() { |
1596 global $wp_list_table; |
|
1597 |
|
1598 check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' ); |
1774 check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' ); |
1599 |
1775 |
1600 $taxonomy = sanitize_key( $_POST['taxonomy'] ); |
1776 $taxonomy = sanitize_key( $_POST['taxonomy'] ); |
1601 $tax = get_taxonomy( $taxonomy ); |
1777 $tax = get_taxonomy( $taxonomy ); |
1602 if ( ! $tax ) |
1778 if ( ! $tax ) |
1603 wp_die( 0 ); |
1779 wp_die( 0 ); |
1604 |
1780 |
1605 if ( ! current_user_can( $tax->cap->edit_terms ) ) |
1781 if ( ! isset( $_POST['tax_ID'] ) || ! ( $id = (int) $_POST['tax_ID'] ) ) { |
1606 wp_die( -1 ); |
1782 wp_die( -1 ); |
1783 } |
|
1784 |
|
1785 if ( ! current_user_can( 'edit_term', $id ) ) { |
|
1786 wp_die( -1 ); |
|
1787 } |
|
1607 |
1788 |
1608 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) ); |
1789 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) ); |
1609 |
|
1610 if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) ) |
|
1611 wp_die( -1 ); |
|
1612 |
1790 |
1613 $tag = get_term( $id, $taxonomy ); |
1791 $tag = get_term( $id, $taxonomy ); |
1614 $_POST['description'] = $tag->description; |
1792 $_POST['description'] = $tag->description; |
1615 |
1793 |
1616 $updated = wp_update_term($id, $taxonomy, $_POST); |
1794 $updated = wp_update_term($id, $taxonomy, $_POST); |
1688 } |
1866 } |
1689 |
1867 |
1690 if ( '0000-00-00 00:00:00' == $post->post_date ) { |
1868 if ( '0000-00-00 00:00:00' == $post->post_date ) { |
1691 $time = ''; |
1869 $time = ''; |
1692 } else { |
1870 } else { |
1693 /* translators: date format in table columns, see http://php.net/date */ |
1871 /* translators: date format in table columns, see https://secure.php.net/date */ |
1694 $time = mysql2date(__('Y/m/d'), $post->post_date); |
1872 $time = mysql2date(__('Y/m/d'), $post->post_date); |
1695 } |
1873 } |
1696 |
1874 |
1697 $html .= '<tr class="' . trim( 'found-posts ' . $alt ) . '"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>'; |
1875 $html .= '<tr class="' . trim( 'found-posts ' . $alt ) . '"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>'; |
1698 $html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n\n"; |
1876 $html .= '<td><label for="found-'.$post->ID.'">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[$post->post_type]->labels->singular_name ) . '</td><td class="no-break">'.esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ). ' </td></tr>' . "\n\n"; |
1717 unset( $_POST['savewidgets'], $_POST['action'] ); |
1895 unset( $_POST['savewidgets'], $_POST['action'] ); |
1718 |
1896 |
1719 // Save widgets order for all sidebars. |
1897 // Save widgets order for all sidebars. |
1720 if ( is_array($_POST['sidebars']) ) { |
1898 if ( is_array($_POST['sidebars']) ) { |
1721 $sidebars = array(); |
1899 $sidebars = array(); |
1722 foreach ( $_POST['sidebars'] as $key => $val ) { |
1900 foreach ( wp_unslash( $_POST['sidebars'] ) as $key => $val ) { |
1723 $sb = array(); |
1901 $sb = array(); |
1724 if ( !empty($val) ) { |
1902 if ( !empty($val) ) { |
1725 $val = explode(',', $val); |
1903 $val = explode(',', $val); |
1726 foreach ( $val as $k => $v ) { |
1904 foreach ( $val as $k => $v ) { |
1727 if ( strpos($v, 'widget-') === false ) |
1905 if ( strpos($v, 'widget-') === false ) |
1741 |
1919 |
1742 /** |
1920 /** |
1743 * Ajax handler for saving a widget. |
1921 * Ajax handler for saving a widget. |
1744 * |
1922 * |
1745 * @since 3.1.0 |
1923 * @since 3.1.0 |
1924 * |
|
1925 * @global array $wp_registered_widgets |
|
1926 * @global array $wp_registered_widget_controls |
|
1927 * @global array $wp_registered_widget_updates |
|
1746 */ |
1928 */ |
1747 function wp_ajax_save_widget() { |
1929 function wp_ajax_save_widget() { |
1748 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; |
1930 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates; |
1749 |
1931 |
1750 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' ); |
1932 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' ); |
1769 do_action( 'widgets.php' ); |
1951 do_action( 'widgets.php' ); |
1770 |
1952 |
1771 /** This action is documented in wp-admin/widgets.php */ |
1953 /** This action is documented in wp-admin/widgets.php */ |
1772 do_action( 'sidebar_admin_setup' ); |
1954 do_action( 'sidebar_admin_setup' ); |
1773 |
1955 |
1774 $id_base = $_POST['id_base']; |
1956 $id_base = wp_unslash( $_POST['id_base'] ); |
1775 $widget_id = $_POST['widget-id']; |
1957 $widget_id = wp_unslash( $_POST['widget-id'] ); |
1776 $sidebar_id = $_POST['sidebar']; |
1958 $sidebar_id = $_POST['sidebar']; |
1777 $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0; |
1959 $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0; |
1778 $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false; |
1960 $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false; |
1779 $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>'; |
1961 $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>'; |
1780 |
1962 |
1787 if ( !isset($wp_registered_widgets[$widget_id]) ) |
1969 if ( !isset($wp_registered_widgets[$widget_id]) ) |
1788 wp_die( $error ); |
1970 wp_die( $error ); |
1789 |
1971 |
1790 $sidebar = array_diff( $sidebar, array($widget_id) ); |
1972 $sidebar = array_diff( $sidebar, array($widget_id) ); |
1791 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); |
1973 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); |
1974 |
|
1975 /** This action is documented in wp-admin/widgets.php */ |
|
1976 do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base ); |
|
1977 |
|
1792 } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) { |
1978 } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) { |
1793 if ( !$multi_number ) |
1979 if ( !$multi_number ) |
1794 wp_die( $error ); |
1980 wp_die( $error ); |
1795 |
1981 |
1796 $_POST[ 'widget-' . $id_base ] = array( $multi_number => reset( $settings ) ); |
1982 $_POST[ 'widget-' . $id_base ] = array( $multi_number => reset( $settings ) ); |
1830 |
2016 |
1831 /** |
2017 /** |
1832 * Ajax handler for saving a widget. |
2018 * Ajax handler for saving a widget. |
1833 * |
2019 * |
1834 * @since 3.9.0 |
2020 * @since 3.9.0 |
2021 * |
|
2022 * @global WP_Customize_Manager $wp_customize |
|
1835 */ |
2023 */ |
1836 function wp_ajax_update_widget() { |
2024 function wp_ajax_update_widget() { |
1837 global $wp_customize; |
2025 global $wp_customize; |
1838 $wp_customize->widgets->wp_ajax_update_widget(); |
2026 $wp_customize->widgets->wp_ajax_update_widget(); |
2027 } |
|
2028 |
|
2029 /** |
|
2030 * Ajax handler for removing inactive widgets. |
|
2031 * |
|
2032 * @since 4.4.0 |
|
2033 */ |
|
2034 function wp_ajax_delete_inactive_widgets() { |
|
2035 check_ajax_referer( 'remove-inactive-widgets', 'removeinactivewidgets' ); |
|
2036 |
|
2037 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
2038 wp_die( -1 ); |
|
2039 } |
|
2040 |
|
2041 unset( $_POST['removeinactivewidgets'], $_POST['action'] ); |
|
2042 /** This action is documented in wp-admin/includes/ajax-actions.php */ |
|
2043 do_action( 'load-widgets.php' ); |
|
2044 /** This action is documented in wp-admin/includes/ajax-actions.php */ |
|
2045 do_action( 'widgets.php' ); |
|
2046 /** This action is documented in wp-admin/widgets.php */ |
|
2047 do_action( 'sidebar_admin_setup' ); |
|
2048 |
|
2049 $sidebars_widgets = wp_get_sidebars_widgets(); |
|
2050 |
|
2051 foreach ( $sidebars_widgets['wp_inactive_widgets'] as $key => $widget_id ) { |
|
2052 $pieces = explode( '-', $widget_id ); |
|
2053 $multi_number = array_pop( $pieces ); |
|
2054 $id_base = implode( '-', $pieces ); |
|
2055 $widget = get_option( 'widget_' . $id_base ); |
|
2056 unset( $widget[$multi_number] ); |
|
2057 update_option( 'widget_' . $id_base, $widget ); |
|
2058 unset( $sidebars_widgets['wp_inactive_widgets'][$key] ); |
|
2059 } |
|
2060 |
|
2061 wp_set_sidebars_widgets( $sidebars_widgets ); |
|
2062 |
|
2063 wp_die(); |
|
1839 } |
2064 } |
1840 |
2065 |
1841 /** |
2066 /** |
1842 * Ajax handler for uploading attachments |
2067 * Ajax handler for uploading attachments |
1843 * |
2068 * |
1853 |
2078 |
1854 if ( ! current_user_can( 'upload_files' ) ) { |
2079 if ( ! current_user_can( 'upload_files' ) ) { |
1855 echo wp_json_encode( array( |
2080 echo wp_json_encode( array( |
1856 'success' => false, |
2081 'success' => false, |
1857 'data' => array( |
2082 'data' => array( |
1858 'message' => __( "You don't have permission to upload files." ), |
2083 'message' => __( 'Sorry, you are not allowed to upload files.' ), |
1859 'filename' => $_FILES['async-upload']['name'], |
2084 'filename' => $_FILES['async-upload']['name'], |
1860 ) |
2085 ) |
1861 ) ); |
2086 ) ); |
1862 |
2087 |
1863 wp_die(); |
2088 wp_die(); |
1867 $post_id = $_REQUEST['post_id']; |
2092 $post_id = $_REQUEST['post_id']; |
1868 if ( ! current_user_can( 'edit_post', $post_id ) ) { |
2093 if ( ! current_user_can( 'edit_post', $post_id ) ) { |
1869 echo wp_json_encode( array( |
2094 echo wp_json_encode( array( |
1870 'success' => false, |
2095 'success' => false, |
1871 'data' => array( |
2096 'data' => array( |
1872 'message' => __( "You don't have permission to attach files to this post." ), |
2097 'message' => __( 'Sorry, you are not allowed to attach files to this post.' ), |
1873 'filename' => $_FILES['async-upload']['name'], |
2098 'filename' => $_FILES['async-upload']['name'], |
1874 ) |
2099 ) |
1875 ) ); |
2100 ) ); |
1876 |
2101 |
1877 wp_die(); |
2102 wp_die(); |
1998 |
2223 |
1999 wp_die( 0 ); |
2224 wp_die( 0 ); |
2000 } |
2225 } |
2001 |
2226 |
2002 /** |
2227 /** |
2003 * AJAX handler for setting the featured image for an attachment. |
2228 * Ajax handler for retrieving HTML for the featured image. |
2229 * |
|
2230 * @since 4.6.0 |
|
2231 */ |
|
2232 function wp_ajax_get_post_thumbnail_html() { |
|
2233 $post_ID = intval( $_POST['post_id'] ); |
|
2234 |
|
2235 check_ajax_referer( "update-post_$post_ID" ); |
|
2236 |
|
2237 if ( ! current_user_can( 'edit_post', $post_ID ) ) { |
|
2238 wp_die( -1 ); |
|
2239 } |
|
2240 |
|
2241 $thumbnail_id = intval( $_POST['thumbnail_id'] ); |
|
2242 |
|
2243 // For backward compatibility, -1 refers to no featured image. |
|
2244 if ( -1 === $thumbnail_id ) { |
|
2245 $thumbnail_id = null; |
|
2246 } |
|
2247 |
|
2248 $return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID ); |
|
2249 wp_send_json_success( $return ); |
|
2250 } |
|
2251 |
|
2252 /** |
|
2253 * Ajax handler for setting the featured image for an attachment. |
|
2004 * |
2254 * |
2005 * @since 4.0.0 |
2255 * @since 4.0.0 |
2006 * |
2256 * |
2007 * @see set_post_thumbnail() |
2257 * @see set_post_thumbnail() |
2008 */ |
2258 */ |
2070 |
2320 |
2071 /** |
2321 /** |
2072 * Ajax handler for saving posts from the fullscreen editor. |
2322 * Ajax handler for saving posts from the fullscreen editor. |
2073 * |
2323 * |
2074 * @since 3.1.0 |
2324 * @since 3.1.0 |
2325 * @deprecated 4.3.0 |
|
2075 */ |
2326 */ |
2076 function wp_ajax_wp_fullscreen_save_post() { |
2327 function wp_ajax_wp_fullscreen_save_post() { |
2077 $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0; |
2328 $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0; |
2078 |
2329 |
2079 $post = null; |
2330 $post = null; |
2088 if ( is_wp_error( $post_id ) ) { |
2339 if ( is_wp_error( $post_id ) ) { |
2089 wp_send_json_error(); |
2340 wp_send_json_error(); |
2090 } |
2341 } |
2091 |
2342 |
2092 if ( $post ) { |
2343 if ( $post ) { |
2093 $last_date = mysql2date( get_option('date_format'), $post->post_modified ); |
2344 $last_date = mysql2date( __( 'F j, Y' ), $post->post_modified ); |
2094 $last_time = mysql2date( get_option('time_format'), $post->post_modified ); |
2345 $last_time = mysql2date( __( 'g:i a' ), $post->post_modified ); |
2095 } else { |
2346 } else { |
2096 $last_date = date_i18n( get_option('date_format') ); |
2347 $last_date = date_i18n( __( 'F j, Y' ) ); |
2097 $last_time = date_i18n( get_option('time_format') ); |
2348 $last_time = date_i18n( __( 'g:i a' ) ); |
2098 } |
2349 } |
2099 |
2350 |
2100 if ( $last_id = get_post_meta( $post_id, '_edit_last', true ) ) { |
2351 if ( $last_id = get_post_meta( $post_id, '_edit_last', true ) ) { |
2101 $last_user = get_userdata( $last_id ); |
2352 $last_user = get_userdata( $last_id ); |
2102 $last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time ); |
2353 $last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time ); |
2127 $active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) ); |
2378 $active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) ); |
2128 if ( $active_lock[1] != get_current_user_id() ) |
2379 if ( $active_lock[1] != get_current_user_id() ) |
2129 wp_die( 0 ); |
2380 wp_die( 0 ); |
2130 |
2381 |
2131 /** |
2382 /** |
2132 * Filter the post lock window duration. |
2383 * Filters the post lock window duration. |
2133 * |
2384 * |
2134 * @since 3.3.0 |
2385 * @since 3.3.0 |
2135 * |
2386 * |
2136 * @param int $interval The interval in seconds the post lock duration |
2387 * @param int $interval The interval in seconds the post lock duration |
2137 * should last, plus 5 seconds. Default 150. |
2388 * should last, plus 5 seconds. Default 150. |
2202 wp_send_json_error(); |
2453 wp_send_json_error(); |
2203 |
2454 |
2204 $query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array(); |
2455 $query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array(); |
2205 $keys = array( |
2456 $keys = array( |
2206 's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type', |
2457 's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type', |
2207 'post_parent', 'post__in', 'post__not_in', 'year', 'monthnum' |
2458 'post_parent', 'author', 'post__in', 'post__not_in', 'year', 'monthnum' |
2208 ); |
2459 ); |
2209 foreach ( get_taxonomies_for_attachments( 'objects' ) as $t ) { |
2460 foreach ( get_taxonomies_for_attachments( 'objects' ) as $t ) { |
2210 if ( $t->query_var && isset( $query[ $t->query_var ] ) ) { |
2461 if ( $t->query_var && isset( $query[ $t->query_var ] ) ) { |
2211 $keys[] = $t->query_var; |
2462 $keys[] = $t->query_var; |
2212 } |
2463 } |
2223 } |
2474 } |
2224 |
2475 |
2225 if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) ) |
2476 if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) ) |
2226 $query['post_status'] .= ',private'; |
2477 $query['post_status'] .= ',private'; |
2227 |
2478 |
2479 // Filter query clauses to include filenames. |
|
2480 if ( isset( $query['s'] ) ) { |
|
2481 add_filter( 'posts_clauses', '_filter_query_attachment_filenames' ); |
|
2482 } |
|
2483 |
|
2228 /** |
2484 /** |
2229 * Filter the arguments passed to WP_Query during an AJAX |
2485 * Filters the arguments passed to WP_Query during an Ajax |
2230 * call for querying attachments. |
2486 * call for querying attachments. |
2231 * |
2487 * |
2232 * @since 3.7.0 |
2488 * @since 3.7.0 |
2233 * |
2489 * |
2234 * @see WP_Query::parse_query() |
2490 * @see WP_Query::parse_query() |
2317 |
2573 |
2318 wp_send_json_success(); |
2574 wp_send_json_success(); |
2319 } |
2575 } |
2320 |
2576 |
2321 /** |
2577 /** |
2322 * Ajax handler for saving backwards compatible attachment attributes. |
2578 * Ajax handler for saving backward compatible attachment attributes. |
2323 * |
2579 * |
2324 * @since 3.5.0 |
2580 * @since 3.5.0 |
2325 */ |
2581 */ |
2326 function wp_ajax_save_attachment_compat() { |
2582 function wp_ajax_save_attachment_compat() { |
2327 if ( ! isset( $_REQUEST['id'] ) ) |
2583 if ( ! isset( $_REQUEST['id'] ) ) |
2403 |
2659 |
2404 /** |
2660 /** |
2405 * Ajax handler for sending an attachment to the editor. |
2661 * Ajax handler for sending an attachment to the editor. |
2406 * |
2662 * |
2407 * Generates the HTML to send an attachment to the editor. |
2663 * Generates the HTML to send an attachment to the editor. |
2408 * Backwards compatible with the media_send_to_editor filter |
2664 * Backward compatible with the {@see 'media_send_to_editor'} filter |
2409 * and the chain of filters that follow. |
2665 * and the chain of filters that follow. |
2410 * |
2666 * |
2411 * @since 3.5.0 |
2667 * @since 3.5.0 |
2412 */ |
2668 */ |
2413 function wp_ajax_send_attachment_to_editor() { |
2669 function wp_ajax_send_attachment_to_editor() { |
2428 if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) { |
2684 if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) { |
2429 wp_update_post( array( 'ID' => $id, 'post_parent' => $insert_into_post_id ) ); |
2685 wp_update_post( array( 'ID' => $id, 'post_parent' => $insert_into_post_id ) ); |
2430 } |
2686 } |
2431 } |
2687 } |
2432 |
2688 |
2433 $rel = $url = ''; |
2689 $url = empty( $attachment['url'] ) ? '' : $attachment['url']; |
2434 $html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : ''; |
2690 $rel = ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url ); |
2435 if ( ! empty( $attachment['url'] ) ) { |
|
2436 $url = $attachment['url']; |
|
2437 if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url ) |
|
2438 $rel = ' rel="attachment wp-att-' . $id . '"'; |
|
2439 $html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>'; |
|
2440 } |
|
2441 |
2691 |
2442 remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' ); |
2692 remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' ); |
2443 |
2693 |
2444 if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) { |
2694 if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) { |
2445 $align = isset( $attachment['align'] ) ? $attachment['align'] : 'none'; |
2695 $align = isset( $attachment['align'] ) ? $attachment['align'] : 'none'; |
2451 if ( '' === trim( $caption ) ) { |
2701 if ( '' === trim( $caption ) ) { |
2452 $caption = ''; |
2702 $caption = ''; |
2453 } |
2703 } |
2454 |
2704 |
2455 $title = ''; // We no longer insert title tags into <img> tags, as they are redundant. |
2705 $title = ''; // We no longer insert title tags into <img> tags, as they are redundant. |
2456 $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt ); |
2706 $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt ); |
2457 } elseif ( wp_attachment_is( 'video', $post ) || wp_attachment_is( 'audio', $post ) ) { |
2707 } elseif ( wp_attachment_is( 'video', $post ) || wp_attachment_is( 'audio', $post ) ) { |
2458 $html = stripslashes_deep( $_POST['html'] ); |
2708 $html = stripslashes_deep( $_POST['html'] ); |
2709 } else { |
|
2710 $html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : ''; |
|
2711 $rel = $rel ? ' rel="attachment wp-att-' . $id . '"' : ''; // Hard-coded string, $id is already sanitized |
|
2712 |
|
2713 if ( ! empty( $url ) ) { |
|
2714 $html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>'; |
|
2715 } |
|
2459 } |
2716 } |
2460 |
2717 |
2461 /** This filter is documented in wp-admin/includes/media.php */ |
2718 /** This filter is documented in wp-admin/includes/media.php */ |
2462 $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment ); |
2719 $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment ); |
2463 |
2720 |
2467 /** |
2724 /** |
2468 * Ajax handler for sending a link to the editor. |
2725 * Ajax handler for sending a link to the editor. |
2469 * |
2726 * |
2470 * Generates the HTML to send a non-image embed link to the editor. |
2727 * Generates the HTML to send a non-image embed link to the editor. |
2471 * |
2728 * |
2472 * Backwards compatible with the following filters: |
2729 * Backward compatible with the following filters: |
2473 * - file_send_to_editor_url |
2730 * - file_send_to_editor_url |
2474 * - audio_send_to_editor_url |
2731 * - audio_send_to_editor_url |
2475 * - video_send_to_editor_url |
2732 * - video_send_to_editor_url |
2476 * |
2733 * |
2477 * @since 3.5.0 |
2734 * @since 3.5.0 |
2735 * |
|
2736 * @global WP_Post $post |
|
2737 * @global WP_Embed $wp_embed |
|
2478 */ |
2738 */ |
2479 function wp_ajax_send_link_to_editor() { |
2739 function wp_ajax_send_link_to_editor() { |
2480 global $post, $wp_embed; |
2740 global $post, $wp_embed; |
2481 |
2741 |
2482 check_ajax_referer( 'media-send-to-editor', 'nonce' ); |
2742 check_ajax_referer( 'media-send-to-editor', 'nonce' ); |
2515 if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) ) |
2775 if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) ) |
2516 && ( 'audio' == $ext_type || 'video' == $ext_type ) ) |
2776 && ( 'audio' == $ext_type || 'video' == $ext_type ) ) |
2517 $type = $ext_type; |
2777 $type = $ext_type; |
2518 |
2778 |
2519 /** This filter is documented in wp-admin/includes/media.php */ |
2779 /** This filter is documented in wp-admin/includes/media.php */ |
2520 $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $link_text ); |
2780 $html = apply_filters( "{$type}_send_to_editor_url", $html, $src, $link_text ); |
2521 |
2781 |
2522 wp_send_json_success( $html ); |
2782 wp_send_json_success( $html ); |
2523 } |
2783 } |
2524 |
2784 |
2525 /** |
2785 /** |
2528 * Runs when the user is logged in. |
2788 * Runs when the user is logged in. |
2529 * |
2789 * |
2530 * @since 3.6.0 |
2790 * @since 3.6.0 |
2531 */ |
2791 */ |
2532 function wp_ajax_heartbeat() { |
2792 function wp_ajax_heartbeat() { |
2533 if ( empty( $_POST['_nonce'] ) ) |
2793 if ( empty( $_POST['_nonce'] ) ) { |
2534 wp_send_json_error(); |
2794 wp_send_json_error(); |
2535 |
2795 } |
2536 $response = array(); |
2796 |
2537 |
2797 $response = $data = array(); |
2538 if ( false === wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' ) ) { |
2798 $nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' ); |
2539 // User is logged in but nonces have expired. |
|
2540 $response['nonces_expired'] = true; |
|
2541 wp_send_json($response); |
|
2542 } |
|
2543 |
2799 |
2544 // screen_id is the same as $current_screen->id and the JS global 'pagenow'. |
2800 // screen_id is the same as $current_screen->id and the JS global 'pagenow'. |
2545 if ( ! empty($_POST['screen_id']) ) |
2801 if ( ! empty( $_POST['screen_id'] ) ) { |
2546 $screen_id = sanitize_key($_POST['screen_id']); |
2802 $screen_id = sanitize_key($_POST['screen_id']); |
2547 else |
2803 } else { |
2548 $screen_id = 'front'; |
2804 $screen_id = 'front'; |
2549 |
2805 } |
2550 if ( ! empty($_POST['data']) ) { |
2806 |
2807 if ( ! empty( $_POST['data'] ) ) { |
|
2551 $data = wp_unslash( (array) $_POST['data'] ); |
2808 $data = wp_unslash( (array) $_POST['data'] ); |
2552 |
2809 } |
2810 |
|
2811 if ( 1 !== $nonce_state ) { |
|
2812 $response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id ); |
|
2813 |
|
2814 if ( false === $nonce_state ) { |
|
2815 // User is logged in but nonces have expired. |
|
2816 $response['nonces_expired'] = true; |
|
2817 wp_send_json( $response ); |
|
2818 } |
|
2819 } |
|
2820 |
|
2821 if ( ! empty( $data ) ) { |
|
2553 /** |
2822 /** |
2554 * Filter the Heartbeat response received. |
2823 * Filters the Heartbeat response received. |
2555 * |
2824 * |
2556 * @since 3.6.0 |
2825 * @since 3.6.0 |
2557 * |
2826 * |
2558 * @param array|object $response The Heartbeat response object or array. |
2827 * @param array $response The Heartbeat response. |
2559 * @param array $data The $_POST data sent. |
2828 * @param array $data The $_POST data sent. |
2560 * @param string $screen_id The screen id. |
2829 * @param string $screen_id The screen id. |
2561 */ |
2830 */ |
2562 $response = apply_filters( 'heartbeat_received', $response, $data, $screen_id ); |
2831 $response = apply_filters( 'heartbeat_received', $response, $data, $screen_id ); |
2563 } |
2832 } |
2564 |
2833 |
2565 /** |
2834 /** |
2566 * Filter the Heartbeat response sent. |
2835 * Filters the Heartbeat response sent. |
2567 * |
2836 * |
2568 * @since 3.6.0 |
2837 * @since 3.6.0 |
2569 * |
2838 * |
2570 * @param array|object $response The Heartbeat response object or array. |
2839 * @param array $response The Heartbeat response. |
2571 * @param string $screen_id The screen id. |
2840 * @param string $screen_id The screen id. |
2572 */ |
2841 */ |
2573 $response = apply_filters( 'heartbeat_send', $response, $screen_id ); |
2842 $response = apply_filters( 'heartbeat_send', $response, $screen_id ); |
2574 |
2843 |
2575 /** |
2844 /** |
2576 * Fires when Heartbeat ticks in logged-in environments. |
2845 * Fires when Heartbeat ticks in logged-in environments. |
2577 * |
2846 * |
2578 * Allows the transport to be easily replaced with long-polling. |
2847 * Allows the transport to be easily replaced with long-polling. |
2579 * |
2848 * |
2580 * @since 3.6.0 |
2849 * @since 3.6.0 |
2581 * |
2850 * |
2582 * @param array|object $response The Heartbeat response object or array. |
2851 * @param array $response The Heartbeat response. |
2583 * @param string $screen_id The screen id. |
2852 * @param string $screen_id The screen id. |
2584 */ |
2853 */ |
2585 do_action( 'heartbeat_tick', $response, $screen_id ); |
2854 do_action( 'heartbeat_tick', $response, $screen_id ); |
2586 |
2855 |
2587 // Send the current time according to the server |
2856 // Send the current time according to the server |
2588 $response['server_time'] = time(); |
2857 $response['server_time'] = time(); |
2589 |
2858 |
2590 wp_send_json($response); |
2859 wp_send_json( $response ); |
2591 } |
2860 } |
2592 |
2861 |
2593 /** |
2862 /** |
2594 * Ajax handler for getting revision diffs. |
2863 * Ajax handler for getting revision diffs. |
2595 * |
2864 * |
2599 require ABSPATH . 'wp-admin/includes/revision.php'; |
2868 require ABSPATH . 'wp-admin/includes/revision.php'; |
2600 |
2869 |
2601 if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) ) |
2870 if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) ) |
2602 wp_send_json_error(); |
2871 wp_send_json_error(); |
2603 |
2872 |
2604 if ( ! current_user_can( 'read_post', $post->ID ) ) |
2873 if ( ! current_user_can( 'edit_post', $post->ID ) ) |
2605 wp_send_json_error(); |
2874 wp_send_json_error(); |
2606 |
2875 |
2607 // Really just pre-loading the cache here. |
2876 // Really just pre-loading the cache here. |
2608 if ( ! $revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) ) ) |
2877 if ( ! $revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) ) ) |
2609 wp_send_json_error(); |
2878 wp_send_json_error(); |
2625 /** |
2894 /** |
2626 * Ajax handler for auto-saving the selected color scheme for |
2895 * Ajax handler for auto-saving the selected color scheme for |
2627 * a user's own profile. |
2896 * a user's own profile. |
2628 * |
2897 * |
2629 * @since 3.8.0 |
2898 * @since 3.8.0 |
2899 * |
|
2900 * @global array $_wp_admin_css_colors |
|
2630 */ |
2901 */ |
2631 function wp_ajax_save_user_color_scheme() { |
2902 function wp_ajax_save_user_color_scheme() { |
2632 global $_wp_admin_css_colors; |
2903 global $_wp_admin_css_colors; |
2633 |
2904 |
2634 check_ajax_referer( 'save-color-scheme', 'nonce' ); |
2905 check_ajax_referer( 'save-color-scheme', 'nonce' ); |
2650 |
2921 |
2651 /** |
2922 /** |
2652 * Ajax handler for getting themes from themes_api(). |
2923 * Ajax handler for getting themes from themes_api(). |
2653 * |
2924 * |
2654 * @since 3.9.0 |
2925 * @since 3.9.0 |
2926 * |
|
2927 * @global array $themes_allowedtags |
|
2928 * @global array $theme_field_defaults |
|
2655 */ |
2929 */ |
2656 function wp_ajax_query_themes() { |
2930 function wp_ajax_query_themes() { |
2657 global $themes_allowedtags, $theme_field_defaults; |
2931 global $themes_allowedtags, $theme_field_defaults; |
2658 |
2932 |
2659 if ( ! current_user_can( 'install_themes' ) ) { |
2933 if ( ! current_user_can( 'install_themes' ) ) { |
2662 |
2936 |
2663 $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array( |
2937 $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array( |
2664 'per_page' => 20, |
2938 'per_page' => 20, |
2665 'fields' => $theme_field_defaults |
2939 'fields' => $theme_field_defaults |
2666 ) ); |
2940 ) ); |
2941 |
|
2942 if ( isset( $args['browse'] ) && 'favorites' === $args['browse'] && ! isset( $args['user'] ) ) { |
|
2943 $user = get_user_option( 'wporg_favorites' ); |
|
2944 if ( $user ) { |
|
2945 $args['user'] = $user; |
|
2946 } |
|
2947 } |
|
2667 |
2948 |
2668 $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search'; |
2949 $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search'; |
2669 |
2950 |
2670 /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */ |
2951 /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */ |
2671 $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args ); |
2952 $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args ); |
2681 $theme->install_url = add_query_arg( array( |
2962 $theme->install_url = add_query_arg( array( |
2682 'theme' => $theme->slug, |
2963 'theme' => $theme->slug, |
2683 '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ) |
2964 '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ) |
2684 ), $update_php ); |
2965 ), $update_php ); |
2685 |
2966 |
2967 if ( current_user_can( 'switch_themes' ) ) { |
|
2968 if ( is_multisite() ) { |
|
2969 $theme->activate_url = add_query_arg( array( |
|
2970 'action' => 'enable', |
|
2971 '_wpnonce' => wp_create_nonce( 'enable-theme_' . $theme->slug ), |
|
2972 'theme' => $theme->slug, |
|
2973 ), network_admin_url( 'themes.php' ) ); |
|
2974 } else { |
|
2975 $theme->activate_url = add_query_arg( array( |
|
2976 'action' => 'activate', |
|
2977 '_wpnonce' => wp_create_nonce( 'switch-theme_' . $theme->slug ), |
|
2978 'stylesheet' => $theme->slug, |
|
2979 ), admin_url( 'themes.php' ) ); |
|
2980 } |
|
2981 } |
|
2982 |
|
2983 if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { |
|
2984 $theme->customize_url = add_query_arg( array( |
|
2985 'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ), |
|
2986 ), wp_customize_url( $theme->slug ) ); |
|
2987 } |
|
2988 |
|
2686 $theme->name = wp_kses( $theme->name, $themes_allowedtags ); |
2989 $theme->name = wp_kses( $theme->name, $themes_allowedtags ); |
2687 $theme->author = wp_kses( $theme->author, $themes_allowedtags ); |
2990 $theme->author = wp_kses( $theme->author, $themes_allowedtags ); |
2688 $theme->version = wp_kses( $theme->version, $themes_allowedtags ); |
2991 $theme->version = wp_kses( $theme->version, $themes_allowedtags ); |
2689 $theme->description = wp_kses( $theme->description, $themes_allowedtags ); |
2992 $theme->description = wp_kses( $theme->description, $themes_allowedtags ); |
2690 $theme->num_ratings = sprintf( _n( '(based on %s rating)', '(based on %s ratings)', $theme->num_ratings ), number_format_i18n( $theme->num_ratings ) ); |
2993 $theme->stars = wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings, 'echo' => false ) ); |
2994 $theme->num_ratings = number_format_i18n( $theme->num_ratings ); |
|
2691 $theme->preview_url = set_url_scheme( $theme->preview_url ); |
2995 $theme->preview_url = set_url_scheme( $theme->preview_url ); |
2692 } |
2996 } |
2693 |
2997 |
2694 wp_send_json_success( $api ); |
2998 wp_send_json_success( $api ); |
2695 } |
2999 } |
2696 |
3000 |
2697 /** |
3001 /** |
2698 * Apply [embed] AJAX handlers to a string. |
3002 * Apply [embed] Ajax handlers to a string. |
2699 * |
3003 * |
2700 * @since 4.0.0 |
3004 * @since 4.0.0 |
2701 * |
3005 * |
2702 * @global WP_Post $post Global $post. |
3006 * @global WP_Post $post Global $post. |
2703 * @global WP_Embed $wp_embed Embed API instance. |
3007 * @global WP_Embed $wp_embed Embed API instance. |
3008 * @global WP_Scripts $wp_scripts |
|
3009 * @global int $content_width |
|
2704 */ |
3010 */ |
2705 function wp_ajax_parse_embed() { |
3011 function wp_ajax_parse_embed() { |
2706 global $post, $wp_embed; |
3012 global $post, $wp_embed, $content_width; |
2707 |
3013 |
2708 if ( ! $post = get_post( (int) $_POST['post_ID'] ) ) { |
3014 if ( empty( $_POST['shortcode'] ) ) { |
2709 wp_send_json_error(); |
3015 wp_send_json_error(); |
2710 } |
3016 } |
2711 |
3017 $post_id = isset( $_POST[ 'post_ID' ] ) ? intval( $_POST[ 'post_ID' ] ) : 0; |
2712 if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'edit_post', $post->ID ) ) { |
3018 if ( $post_id > 0 ) { |
3019 $post = get_post( $post_id ); |
|
3020 if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { |
|
3021 wp_send_json_error(); |
|
3022 } |
|
3023 setup_postdata( $post ); |
|
3024 } elseif ( ! current_user_can( 'edit_posts' ) ) { // See WP_oEmbed_Controller::get_proxy_item_permissions_check(). |
|
2713 wp_send_json_error(); |
3025 wp_send_json_error(); |
2714 } |
3026 } |
2715 |
3027 |
2716 $shortcode = wp_unslash( $_POST['shortcode'] ); |
3028 $shortcode = wp_unslash( $_POST['shortcode'] ); |
2717 $url = str_replace( '[embed]', '', str_replace( '[/embed]', '', $shortcode ) ); |
3029 |
3030 preg_match( '/' . get_shortcode_regex() . '/s', $shortcode, $matches ); |
|
3031 $atts = shortcode_parse_atts( $matches[3] ); |
|
3032 if ( ! empty( $matches[5] ) ) { |
|
3033 $url = $matches[5]; |
|
3034 } elseif ( ! empty( $atts['src'] ) ) { |
|
3035 $url = $atts['src']; |
|
3036 } else { |
|
3037 $url = ''; |
|
3038 } |
|
2718 |
3039 |
2719 $parsed = false; |
3040 $parsed = false; |
2720 setup_postdata( $post ); |
|
2721 |
|
2722 $wp_embed->return_false_on_fail = true; |
3041 $wp_embed->return_false_on_fail = true; |
2723 |
3042 |
2724 if ( is_ssl() && preg_match( '%^\\[embed[^\\]]*\\]http://%i', $shortcode ) ) { |
3043 if ( 0 === $post_id ) { |
3044 /* |
|
3045 * Refresh oEmbeds cached outside of posts that are past their TTL. |
|
3046 * Posts are excluded because they have separate logic for refreshing |
|
3047 * their post meta caches. See WP_Embed::cache_oembed(). |
|
3048 */ |
|
3049 $wp_embed->usecache = false; |
|
3050 } |
|
3051 |
|
3052 if ( is_ssl() && 0 === strpos( $url, 'http://' ) ) { |
|
2725 // Admin is ssl and the user pasted non-ssl URL. |
3053 // Admin is ssl and the user pasted non-ssl URL. |
2726 // Check if the provider supports ssl embeds and use that for the preview. |
3054 // Check if the provider supports ssl embeds and use that for the preview. |
2727 $ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode ); |
3055 $ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode ); |
2728 $parsed = $wp_embed->run_shortcode( $ssl_shortcode ); |
3056 $parsed = $wp_embed->run_shortcode( $ssl_shortcode ); |
2729 |
3057 |
2730 if ( ! $parsed ) { |
3058 if ( ! $parsed ) { |
2731 $no_ssl_support = true; |
3059 $no_ssl_support = true; |
2732 } |
3060 } |
2733 } |
3061 } |
2734 |
3062 |
2735 if ( ! $parsed ) { |
3063 // Set $content_width so any embeds fit in the destination iframe. |
3064 if ( isset( $_POST['maxwidth'] ) && is_numeric( $_POST['maxwidth'] ) && $_POST['maxwidth'] > 0 ) { |
|
3065 if ( ! isset( $content_width ) ) { |
|
3066 $content_width = intval( $_POST['maxwidth'] ); |
|
3067 } else { |
|
3068 $content_width = min( $content_width, intval( $_POST['maxwidth'] ) ); |
|
3069 } |
|
3070 } |
|
3071 |
|
3072 if ( $url && ! $parsed ) { |
|
2736 $parsed = $wp_embed->run_shortcode( $shortcode ); |
3073 $parsed = $wp_embed->run_shortcode( $shortcode ); |
2737 } |
3074 } |
2738 |
3075 |
2739 if ( ! $parsed ) { |
3076 if ( ! $parsed ) { |
2740 wp_send_json_error( array( |
3077 wp_send_json_error( array( |
2755 global $wp_scripts; |
3092 global $wp_scripts; |
2756 if ( ! empty( $wp_scripts ) ) { |
3093 if ( ! empty( $wp_scripts ) ) { |
2757 $wp_scripts->done = array(); |
3094 $wp_scripts->done = array(); |
2758 } |
3095 } |
2759 ob_start(); |
3096 ob_start(); |
2760 wp_print_scripts( 'wp-mediaelement' ); |
3097 wp_print_scripts( array( 'mediaelement-vimeo', 'wp-mediaelement' ) ); |
2761 $scripts = ob_get_clean(); |
3098 $scripts = ob_get_clean(); |
2762 |
3099 |
2763 $parsed = $styles . $html . $scripts; |
3100 $parsed = $styles . $html . $scripts; |
2764 } |
3101 } |
2765 |
|
2766 |
3102 |
2767 if ( ! empty( $no_ssl_support ) || ( is_ssl() && ( preg_match( '%<(iframe|script|embed) [^>]*src="http://%', $parsed ) || |
3103 if ( ! empty( $no_ssl_support ) || ( is_ssl() && ( preg_match( '%<(iframe|script|embed) [^>]*src="http://%', $parsed ) || |
2768 preg_match( '%<link [^>]*href="http://%', $parsed ) ) ) ) { |
3104 preg_match( '%<link [^>]*href="http://%', $parsed ) ) ) ) { |
2769 // Admin is ssl and the embed is not. Iframes, scripts, and other "active content" will be blocked. |
3105 // Admin is ssl and the embed is not. Iframes, scripts, and other "active content" will be blocked. |
2770 wp_send_json_error( array( |
3106 wp_send_json_error( array( |
2771 'type' => 'not-ssl', |
3107 'type' => 'not-ssl', |
2772 'message' => __( 'This preview is unavailable in the editor.' ), |
3108 'message' => __( 'This preview is unavailable in the editor.' ), |
2773 ) ); |
3109 ) ); |
2774 } |
3110 } |
2775 |
3111 |
2776 wp_send_json_success( array( |
3112 $return = array( |
2777 'body' => $parsed |
3113 'body' => $parsed, |
2778 ) ); |
3114 'attr' => $wp_embed->last_attr |
2779 } |
3115 ); |
2780 |
3116 |
3117 if ( strpos( $parsed, 'class="wp-embedded-content' ) ) { |
|
3118 if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { |
|
3119 $script_src = includes_url( 'js/wp-embed.js' ); |
|
3120 } else { |
|
3121 $script_src = includes_url( 'js/wp-embed.min.js' ); |
|
3122 } |
|
3123 |
|
3124 $return['head'] = '<script src="' . $script_src . '"></script>'; |
|
3125 $return['sandbox'] = true; |
|
3126 } |
|
3127 |
|
3128 wp_send_json_success( $return ); |
|
3129 } |
|
3130 |
|
3131 /** |
|
3132 * @since 4.0.0 |
|
3133 * |
|
3134 * @global WP_Post $post |
|
3135 * @global WP_Scripts $wp_scripts |
|
3136 */ |
|
2781 function wp_ajax_parse_media_shortcode() { |
3137 function wp_ajax_parse_media_shortcode() { |
2782 global $post, $wp_scripts; |
3138 global $post, $wp_scripts; |
2783 |
3139 |
2784 if ( empty( $_POST['shortcode'] ) ) { |
3140 if ( empty( $_POST['shortcode'] ) ) { |
2785 wp_send_json_error(); |
3141 wp_send_json_error(); |
2827 if ( 'playlist' === $_REQUEST['type'] ) { |
3183 if ( 'playlist' === $_REQUEST['type'] ) { |
2828 wp_underscore_playlist_templates(); |
3184 wp_underscore_playlist_templates(); |
2829 |
3185 |
2830 wp_print_scripts( 'wp-playlist' ); |
3186 wp_print_scripts( 'wp-playlist' ); |
2831 } else { |
3187 } else { |
2832 wp_print_scripts( array( 'froogaloop', 'wp-mediaelement' ) ); |
3188 wp_print_scripts( array( 'mediaelement-vimeo', 'wp-mediaelement' ) ); |
2833 } |
3189 } |
2834 |
3190 |
2835 wp_send_json_success( array( |
3191 wp_send_json_success( array( |
2836 'head' => $head, |
3192 'head' => $head, |
2837 'body' => ob_get_clean() |
3193 'body' => ob_get_clean() |
2838 ) ); |
3194 ) ); |
2839 } |
3195 } |
2840 |
3196 |
2841 /** |
3197 /** |
2842 * AJAX handler for destroying multiple open sessions for a user. |
3198 * Ajax handler for destroying multiple open sessions for a user. |
2843 * |
3199 * |
2844 * @since 4.1.0 |
3200 * @since 4.1.0 |
2845 */ |
3201 */ |
2846 function wp_ajax_destroy_sessions() { |
3202 function wp_ajax_destroy_sessions() { |
2847 |
|
2848 $user = get_userdata( (int) $_POST['user_id'] ); |
3203 $user = get_userdata( (int) $_POST['user_id'] ); |
2849 if ( $user ) { |
3204 if ( $user ) { |
2850 if ( ! current_user_can( 'edit_user', $user->ID ) ) { |
3205 if ( ! current_user_can( 'edit_user', $user->ID ) ) { |
2851 $user = false; |
3206 $user = false; |
2852 } elseif ( ! wp_verify_nonce( $_POST['nonce'], 'update-user_' . $user->ID ) ) { |
3207 } elseif ( ! wp_verify_nonce( $_POST['nonce'], 'update-user_' . $user->ID ) ) { |
2865 if ( $user->ID === get_current_user_id() ) { |
3220 if ( $user->ID === get_current_user_id() ) { |
2866 $sessions->destroy_others( wp_get_session_token() ); |
3221 $sessions->destroy_others( wp_get_session_token() ); |
2867 $message = __( 'You are now logged out everywhere else.' ); |
3222 $message = __( 'You are now logged out everywhere else.' ); |
2868 } else { |
3223 } else { |
2869 $sessions->destroy_all(); |
3224 $sessions->destroy_all(); |
2870 /* translators: 1: User's display name. */ |
3225 /* translators: %s: User's display name. */ |
2871 $message = sprintf( __( '%s has been logged out.' ), $user->display_name ); |
3226 $message = sprintf( __( '%s has been logged out.' ), $user->display_name ); |
2872 } |
3227 } |
2873 |
3228 |
2874 wp_send_json_success( array( 'message' => $message ) ); |
3229 wp_send_json_success( array( 'message' => $message ) ); |
2875 } |
3230 } |
2876 |
3231 |
2877 |
3232 /** |
2878 /** |
3233 * Ajax handler for cropping an image. |
2879 * AJAX handler for updating a plugin. |
3234 * |
2880 * |
3235 * @since 4.3.0 |
2881 * @since 4.2.0 |
3236 */ |
2882 * |
3237 function wp_ajax_crop_image() { |
2883 * @see Plugin_Upgrader |
3238 $attachment_id = absint( $_POST['id'] ); |
2884 */ |
3239 |
2885 function wp_ajax_update_plugin() { |
3240 check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' ); |
2886 $plugin = urldecode( $_POST['plugin'] ); |
3241 if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) { |
3242 wp_send_json_error(); |
|
3243 } |
|
3244 |
|
3245 $context = str_replace( '_', '-', $_POST['context'] ); |
|
3246 $data = array_map( 'absint', $_POST['cropDetails'] ); |
|
3247 $cropped = wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] ); |
|
3248 |
|
3249 if ( ! $cropped || is_wp_error( $cropped ) ) { |
|
3250 wp_send_json_error( array( 'message' => __( 'Image could not be processed.' ) ) ); |
|
3251 } |
|
3252 |
|
3253 switch ( $context ) { |
|
3254 case 'site-icon': |
|
3255 require_once ABSPATH . '/wp-admin/includes/class-wp-site-icon.php'; |
|
3256 $wp_site_icon = new WP_Site_Icon(); |
|
3257 |
|
3258 // Skip creating a new attachment if the attachment is a Site Icon. |
|
3259 if ( get_post_meta( $attachment_id, '_wp_attachment_context', true ) == $context ) { |
|
3260 |
|
3261 // Delete the temporary cropped file, we don't need it. |
|
3262 wp_delete_file( $cropped ); |
|
3263 |
|
3264 // Additional sizes in wp_prepare_attachment_for_js(). |
|
3265 add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); |
|
3266 break; |
|
3267 } |
|
3268 |
|
3269 /** This filter is documented in wp-admin/custom-header.php */ |
|
3270 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. |
|
3271 $object = $wp_site_icon->create_attachment_object( $cropped, $attachment_id ); |
|
3272 unset( $object['ID'] ); |
|
3273 |
|
3274 // Update the attachment. |
|
3275 add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); |
|
3276 $attachment_id = $wp_site_icon->insert_attachment( $object, $cropped ); |
|
3277 remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); |
|
3278 |
|
3279 // Additional sizes in wp_prepare_attachment_for_js(). |
|
3280 add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) ); |
|
3281 break; |
|
3282 |
|
3283 default: |
|
3284 |
|
3285 /** |
|
3286 * Fires before a cropped image is saved. |
|
3287 * |
|
3288 * Allows to add filters to modify the way a cropped image is saved. |
|
3289 * |
|
3290 * @since 4.3.0 |
|
3291 * |
|
3292 * @param string $context The Customizer control requesting the cropped image. |
|
3293 * @param int $attachment_id The attachment ID of the original image. |
|
3294 * @param string $cropped Path to the cropped image file. |
|
3295 */ |
|
3296 do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped ); |
|
3297 |
|
3298 /** This filter is documented in wp-admin/custom-header.php */ |
|
3299 $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. |
|
3300 |
|
3301 $parent_url = wp_get_attachment_url( $attachment_id ); |
|
3302 $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url ); |
|
3303 |
|
3304 $size = @getimagesize( $cropped ); |
|
3305 $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; |
|
3306 |
|
3307 $object = array( |
|
3308 'post_title' => basename( $cropped ), |
|
3309 'post_content' => $url, |
|
3310 'post_mime_type' => $image_type, |
|
3311 'guid' => $url, |
|
3312 'context' => $context, |
|
3313 ); |
|
3314 |
|
3315 $attachment_id = wp_insert_attachment( $object, $cropped ); |
|
3316 $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped ); |
|
3317 |
|
3318 /** |
|
3319 * Filters the cropped image attachment metadata. |
|
3320 * |
|
3321 * @since 4.3.0 |
|
3322 * |
|
3323 * @see wp_generate_attachment_metadata() |
|
3324 * |
|
3325 * @param array $metadata Attachment metadata. |
|
3326 */ |
|
3327 $metadata = apply_filters( 'wp_ajax_cropped_attachment_metadata', $metadata ); |
|
3328 wp_update_attachment_metadata( $attachment_id, $metadata ); |
|
3329 |
|
3330 /** |
|
3331 * Filters the attachment ID for a cropped image. |
|
3332 * |
|
3333 * @since 4.3.0 |
|
3334 * |
|
3335 * @param int $attachment_id The attachment ID of the cropped image. |
|
3336 * @param string $context The Customizer control requesting the cropped image. |
|
3337 */ |
|
3338 $attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', $attachment_id, $context ); |
|
3339 } |
|
3340 |
|
3341 wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) ); |
|
3342 } |
|
3343 |
|
3344 /** |
|
3345 * Ajax handler for generating a password. |
|
3346 * |
|
3347 * @since 4.4.0 |
|
3348 */ |
|
3349 function wp_ajax_generate_password() { |
|
3350 wp_send_json_success( wp_generate_password( 24 ) ); |
|
3351 } |
|
3352 |
|
3353 /** |
|
3354 * Ajax handler for saving the user's WordPress.org username. |
|
3355 * |
|
3356 * @since 4.4.0 |
|
3357 */ |
|
3358 function wp_ajax_save_wporg_username() { |
|
3359 if ( ! current_user_can( 'install_themes' ) && ! current_user_can( 'install_plugins' ) ) { |
|
3360 wp_send_json_error(); |
|
3361 } |
|
3362 |
|
3363 check_ajax_referer( 'save_wporg_username_' . get_current_user_id() ); |
|
3364 |
|
3365 $username = isset( $_REQUEST['username'] ) ? wp_unslash( $_REQUEST['username'] ) : false; |
|
3366 |
|
3367 if ( ! $username ) { |
|
3368 wp_send_json_error(); |
|
3369 } |
|
3370 |
|
3371 wp_send_json_success( update_user_meta( get_current_user_id(), 'wporg_favorites', $username ) ); |
|
3372 } |
|
3373 |
|
3374 /** |
|
3375 * Ajax handler for installing a theme. |
|
3376 * |
|
3377 * @since 4.6.0 |
|
3378 * |
|
3379 * @see Theme_Upgrader |
|
3380 * |
|
3381 * @global WP_Filesystem_Base $wp_filesystem Subclass |
|
3382 */ |
|
3383 function wp_ajax_install_theme() { |
|
3384 check_ajax_referer( 'updates' ); |
|
3385 |
|
3386 if ( empty( $_POST['slug'] ) ) { |
|
3387 wp_send_json_error( array( |
|
3388 'slug' => '', |
|
3389 'errorCode' => 'no_theme_specified', |
|
3390 'errorMessage' => __( 'No theme specified.' ), |
|
3391 ) ); |
|
3392 } |
|
3393 |
|
3394 $slug = sanitize_key( wp_unslash( $_POST['slug'] ) ); |
|
2887 |
3395 |
2888 $status = array( |
3396 $status = array( |
2889 'update' => 'plugin', |
3397 'install' => 'theme', |
2890 'plugin' => $plugin, |
3398 'slug' => $slug, |
2891 'slug' => sanitize_key( $_POST['slug'] ), |
3399 ); |
3400 |
|
3401 if ( ! current_user_can( 'install_themes' ) ) { |
|
3402 $status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' ); |
|
3403 wp_send_json_error( $status ); |
|
3404 } |
|
3405 |
|
3406 include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); |
|
3407 include_once( ABSPATH . 'wp-admin/includes/theme.php' ); |
|
3408 |
|
3409 $api = themes_api( 'theme_information', array( |
|
3410 'slug' => $slug, |
|
3411 'fields' => array( 'sections' => false ), |
|
3412 ) ); |
|
3413 |
|
3414 if ( is_wp_error( $api ) ) { |
|
3415 $status['errorMessage'] = $api->get_error_message(); |
|
3416 wp_send_json_error( $status ); |
|
3417 } |
|
3418 |
|
3419 $skin = new WP_Ajax_Upgrader_Skin(); |
|
3420 $upgrader = new Theme_Upgrader( $skin ); |
|
3421 $result = $upgrader->install( $api->download_link ); |
|
3422 |
|
3423 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
|
3424 $status['debug'] = $skin->get_upgrade_messages(); |
|
3425 } |
|
3426 |
|
3427 if ( is_wp_error( $result ) ) { |
|
3428 $status['errorCode'] = $result->get_error_code(); |
|
3429 $status['errorMessage'] = $result->get_error_message(); |
|
3430 wp_send_json_error( $status ); |
|
3431 } elseif ( is_wp_error( $skin->result ) ) { |
|
3432 $status['errorCode'] = $skin->result->get_error_code(); |
|
3433 $status['errorMessage'] = $skin->result->get_error_message(); |
|
3434 wp_send_json_error( $status ); |
|
3435 } elseif ( $skin->get_errors()->get_error_code() ) { |
|
3436 $status['errorMessage'] = $skin->get_error_messages(); |
|
3437 wp_send_json_error( $status ); |
|
3438 } elseif ( is_null( $result ) ) { |
|
3439 global $wp_filesystem; |
|
3440 |
|
3441 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
|
3442 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
|
3443 |
|
3444 // Pass through the error from WP_Filesystem if one was raised. |
|
3445 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3446 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3447 } |
|
3448 |
|
3449 wp_send_json_error( $status ); |
|
3450 } |
|
3451 |
|
3452 $status['themeName'] = wp_get_theme( $slug )->get( 'Name' ); |
|
3453 |
|
3454 if ( current_user_can( 'switch_themes' ) ) { |
|
3455 if ( is_multisite() ) { |
|
3456 $status['activateUrl'] = add_query_arg( array( |
|
3457 'action' => 'enable', |
|
3458 '_wpnonce' => wp_create_nonce( 'enable-theme_' . $slug ), |
|
3459 'theme' => $slug, |
|
3460 ), network_admin_url( 'themes.php' ) ); |
|
3461 } else { |
|
3462 $status['activateUrl'] = add_query_arg( array( |
|
3463 'action' => 'activate', |
|
3464 '_wpnonce' => wp_create_nonce( 'switch-theme_' . $slug ), |
|
3465 'stylesheet' => $slug, |
|
3466 ), admin_url( 'themes.php' ) ); |
|
3467 } |
|
3468 } |
|
3469 |
|
3470 if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { |
|
3471 $status['customizeUrl'] = add_query_arg( array( |
|
3472 'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ), |
|
3473 ), wp_customize_url( $slug ) ); |
|
3474 } |
|
3475 |
|
3476 /* |
|
3477 * See WP_Theme_Install_List_Table::_get_theme_status() if we wanted to check |
|
3478 * on post-installation status. |
|
3479 */ |
|
3480 wp_send_json_success( $status ); |
|
3481 } |
|
3482 |
|
3483 /** |
|
3484 * Ajax handler for updating a theme. |
|
3485 * |
|
3486 * @since 4.6.0 |
|
3487 * |
|
3488 * @see Theme_Upgrader |
|
3489 * |
|
3490 * @global WP_Filesystem_Base $wp_filesystem Subclass |
|
3491 */ |
|
3492 function wp_ajax_update_theme() { |
|
3493 check_ajax_referer( 'updates' ); |
|
3494 |
|
3495 if ( empty( $_POST['slug'] ) ) { |
|
3496 wp_send_json_error( array( |
|
3497 'slug' => '', |
|
3498 'errorCode' => 'no_theme_specified', |
|
3499 'errorMessage' => __( 'No theme specified.' ), |
|
3500 ) ); |
|
3501 } |
|
3502 |
|
3503 $stylesheet = preg_replace( '/[^A-z0-9_\-]/', '', wp_unslash( $_POST['slug'] ) ); |
|
3504 $status = array( |
|
3505 'update' => 'theme', |
|
3506 'slug' => $stylesheet, |
|
2892 'oldVersion' => '', |
3507 'oldVersion' => '', |
2893 'newVersion' => '', |
3508 'newVersion' => '', |
2894 ); |
3509 ); |
2895 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
3510 |
3511 if ( ! current_user_can( 'update_themes' ) ) { |
|
3512 $status['errorMessage'] = __( 'Sorry, you are not allowed to update themes for this site.' ); |
|
3513 wp_send_json_error( $status ); |
|
3514 } |
|
3515 |
|
3516 $theme = wp_get_theme( $stylesheet ); |
|
3517 if ( $theme->exists() ) { |
|
3518 $status['oldVersion'] = $theme->get( 'Version' ); |
|
3519 } |
|
3520 |
|
3521 include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); |
|
3522 |
|
3523 $current = get_site_transient( 'update_themes' ); |
|
3524 if ( empty( $current ) ) { |
|
3525 wp_update_themes(); |
|
3526 } |
|
3527 |
|
3528 $skin = new WP_Ajax_Upgrader_Skin(); |
|
3529 $upgrader = new Theme_Upgrader( $skin ); |
|
3530 $result = $upgrader->bulk_upgrade( array( $stylesheet ) ); |
|
3531 |
|
3532 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
|
3533 $status['debug'] = $skin->get_upgrade_messages(); |
|
3534 } |
|
3535 |
|
3536 if ( is_wp_error( $skin->result ) ) { |
|
3537 $status['errorCode'] = $skin->result->get_error_code(); |
|
3538 $status['errorMessage'] = $skin->result->get_error_message(); |
|
3539 wp_send_json_error( $status ); |
|
3540 } elseif ( $skin->get_errors()->get_error_code() ) { |
|
3541 $status['errorMessage'] = $skin->get_error_messages(); |
|
3542 wp_send_json_error( $status ); |
|
3543 } elseif ( is_array( $result ) && ! empty( $result[ $stylesheet ] ) ) { |
|
3544 |
|
3545 // Theme is already at the latest version. |
|
3546 if ( true === $result[ $stylesheet ] ) { |
|
3547 $status['errorMessage'] = $upgrader->strings['up_to_date']; |
|
3548 wp_send_json_error( $status ); |
|
3549 } |
|
3550 |
|
3551 $theme = wp_get_theme( $stylesheet ); |
|
3552 if ( $theme->exists() ) { |
|
3553 $status['newVersion'] = $theme->get( 'Version' ); |
|
3554 } |
|
3555 |
|
3556 wp_send_json_success( $status ); |
|
3557 } elseif ( false === $result ) { |
|
3558 global $wp_filesystem; |
|
3559 |
|
3560 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
|
3561 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
|
3562 |
|
3563 // Pass through the error from WP_Filesystem if one was raised. |
|
3564 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3565 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3566 } |
|
3567 |
|
3568 wp_send_json_error( $status ); |
|
3569 } |
|
3570 |
|
3571 // An unhandled error occurred. |
|
3572 $status['errorMessage'] = __( 'Update failed.' ); |
|
3573 wp_send_json_error( $status ); |
|
3574 } |
|
3575 |
|
3576 /** |
|
3577 * Ajax handler for deleting a theme. |
|
3578 * |
|
3579 * @since 4.6.0 |
|
3580 * |
|
3581 * @see delete_theme() |
|
3582 * |
|
3583 * @global WP_Filesystem_Base $wp_filesystem Subclass |
|
3584 */ |
|
3585 function wp_ajax_delete_theme() { |
|
3586 check_ajax_referer( 'updates' ); |
|
3587 |
|
3588 if ( empty( $_POST['slug'] ) ) { |
|
3589 wp_send_json_error( array( |
|
3590 'slug' => '', |
|
3591 'errorCode' => 'no_theme_specified', |
|
3592 'errorMessage' => __( 'No theme specified.' ), |
|
3593 ) ); |
|
3594 } |
|
3595 |
|
3596 $stylesheet = preg_replace( '/[^A-z0-9_\-]/', '', wp_unslash( $_POST['slug'] ) ); |
|
3597 $status = array( |
|
3598 'delete' => 'theme', |
|
3599 'slug' => $stylesheet, |
|
3600 ); |
|
3601 |
|
3602 if ( ! current_user_can( 'delete_themes' ) ) { |
|
3603 $status['errorMessage'] = __( 'Sorry, you are not allowed to delete themes on this site.' ); |
|
3604 wp_send_json_error( $status ); |
|
3605 } |
|
3606 |
|
3607 if ( ! wp_get_theme( $stylesheet )->exists() ) { |
|
3608 $status['errorMessage'] = __( 'The requested theme does not exist.' ); |
|
3609 wp_send_json_error( $status ); |
|
3610 } |
|
3611 |
|
3612 // Check filesystem credentials. `delete_theme()` will bail otherwise. |
|
3613 $url = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet ); |
|
3614 ob_start(); |
|
3615 $credentials = request_filesystem_credentials( $url ); |
|
3616 ob_end_clean(); |
|
3617 if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { |
|
3618 global $wp_filesystem; |
|
3619 |
|
3620 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
|
3621 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
|
3622 |
|
3623 // Pass through the error from WP_Filesystem if one was raised. |
|
3624 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3625 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3626 } |
|
3627 |
|
3628 wp_send_json_error( $status ); |
|
3629 } |
|
3630 |
|
3631 include_once( ABSPATH . 'wp-admin/includes/theme.php' ); |
|
3632 |
|
3633 $result = delete_theme( $stylesheet ); |
|
3634 |
|
3635 if ( is_wp_error( $result ) ) { |
|
3636 $status['errorMessage'] = $result->get_error_message(); |
|
3637 wp_send_json_error( $status ); |
|
3638 } elseif ( false === $result ) { |
|
3639 $status['errorMessage'] = __( 'Theme could not be deleted.' ); |
|
3640 wp_send_json_error( $status ); |
|
3641 } |
|
3642 |
|
3643 wp_send_json_success( $status ); |
|
3644 } |
|
3645 |
|
3646 /** |
|
3647 * Ajax handler for installing a plugin. |
|
3648 * |
|
3649 * @since 4.6.0 |
|
3650 * |
|
3651 * @see Plugin_Upgrader |
|
3652 * |
|
3653 * @global WP_Filesystem_Base $wp_filesystem Subclass |
|
3654 */ |
|
3655 function wp_ajax_install_plugin() { |
|
3656 check_ajax_referer( 'updates' ); |
|
3657 |
|
3658 if ( empty( $_POST['slug'] ) ) { |
|
3659 wp_send_json_error( array( |
|
3660 'slug' => '', |
|
3661 'errorCode' => 'no_plugin_specified', |
|
3662 'errorMessage' => __( 'No plugin specified.' ), |
|
3663 ) ); |
|
3664 } |
|
3665 |
|
3666 $status = array( |
|
3667 'install' => 'plugin', |
|
3668 'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ), |
|
3669 ); |
|
3670 |
|
3671 if ( ! current_user_can( 'install_plugins' ) ) { |
|
3672 $status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' ); |
|
3673 wp_send_json_error( $status ); |
|
3674 } |
|
3675 |
|
3676 include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); |
|
3677 include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); |
|
3678 |
|
3679 $api = plugins_api( 'plugin_information', array( |
|
3680 'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ), |
|
3681 'fields' => array( |
|
3682 'sections' => false, |
|
3683 ), |
|
3684 ) ); |
|
3685 |
|
3686 if ( is_wp_error( $api ) ) { |
|
3687 $status['errorMessage'] = $api->get_error_message(); |
|
3688 wp_send_json_error( $status ); |
|
3689 } |
|
3690 |
|
3691 $status['pluginName'] = $api->name; |
|
3692 |
|
3693 $skin = new WP_Ajax_Upgrader_Skin(); |
|
3694 $upgrader = new Plugin_Upgrader( $skin ); |
|
3695 $result = $upgrader->install( $api->download_link ); |
|
3696 |
|
3697 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
|
3698 $status['debug'] = $skin->get_upgrade_messages(); |
|
3699 } |
|
3700 |
|
3701 if ( is_wp_error( $result ) ) { |
|
3702 $status['errorCode'] = $result->get_error_code(); |
|
3703 $status['errorMessage'] = $result->get_error_message(); |
|
3704 wp_send_json_error( $status ); |
|
3705 } elseif ( is_wp_error( $skin->result ) ) { |
|
3706 $status['errorCode'] = $skin->result->get_error_code(); |
|
3707 $status['errorMessage'] = $skin->result->get_error_message(); |
|
3708 wp_send_json_error( $status ); |
|
3709 } elseif ( $skin->get_errors()->get_error_code() ) { |
|
3710 $status['errorMessage'] = $skin->get_error_messages(); |
|
3711 wp_send_json_error( $status ); |
|
3712 } elseif ( is_null( $result ) ) { |
|
3713 global $wp_filesystem; |
|
3714 |
|
3715 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
|
3716 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
|
3717 |
|
3718 // Pass through the error from WP_Filesystem if one was raised. |
|
3719 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3720 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3721 } |
|
3722 |
|
3723 wp_send_json_error( $status ); |
|
3724 } |
|
3725 |
|
3726 $install_status = install_plugin_install_status( $api ); |
|
3727 $pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : ''; |
|
3728 |
|
3729 // If installation request is coming from import page, do not return network activation link. |
|
3730 $plugins_url = ( 'import' === $pagenow ) ? admin_url( 'plugins.php' ) : network_admin_url( 'plugins.php' ); |
|
3731 |
|
3732 if ( current_user_can( 'activate_plugin', $install_status['file'] ) && is_plugin_inactive( $install_status['file'] ) ) { |
|
3733 $status['activateUrl'] = add_query_arg( array( |
|
3734 '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $install_status['file'] ), |
|
3735 'action' => 'activate', |
|
3736 'plugin' => $install_status['file'], |
|
3737 ), $plugins_url ); |
|
3738 } |
|
3739 |
|
3740 if ( is_multisite() && current_user_can( 'manage_network_plugins' ) && 'import' !== $pagenow ) { |
|
3741 $status['activateUrl'] = add_query_arg( array( 'networkwide' => 1 ), $status['activateUrl'] ); |
|
3742 } |
|
3743 |
|
3744 wp_send_json_success( $status ); |
|
3745 } |
|
3746 |
|
3747 /** |
|
3748 * Ajax handler for updating a plugin. |
|
3749 * |
|
3750 * @since 4.2.0 |
|
3751 * |
|
3752 * @see Plugin_Upgrader |
|
3753 * |
|
3754 * @global WP_Filesystem_Base $wp_filesystem Subclass |
|
3755 */ |
|
3756 function wp_ajax_update_plugin() { |
|
3757 check_ajax_referer( 'updates' ); |
|
3758 |
|
3759 if ( empty( $_POST['plugin'] ) || empty( $_POST['slug'] ) ) { |
|
3760 wp_send_json_error( array( |
|
3761 'slug' => '', |
|
3762 'errorCode' => 'no_plugin_specified', |
|
3763 'errorMessage' => __( 'No plugin specified.' ), |
|
3764 ) ); |
|
3765 } |
|
3766 |
|
3767 $plugin = plugin_basename( sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) ); |
|
3768 |
|
3769 $status = array( |
|
3770 'update' => 'plugin', |
|
3771 'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ), |
|
3772 'oldVersion' => '', |
|
3773 'newVersion' => '', |
|
3774 ); |
|
3775 |
|
3776 if ( ! current_user_can( 'update_plugins' ) || 0 !== validate_file( $plugin ) ) { |
|
3777 $status['errorMessage'] = __( 'Sorry, you are not allowed to update plugins for this site.' ); |
|
3778 wp_send_json_error( $status ); |
|
3779 } |
|
3780 |
|
3781 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
|
3782 $status['plugin'] = $plugin; |
|
3783 $status['pluginName'] = $plugin_data['Name']; |
|
3784 |
|
2896 if ( $plugin_data['Version'] ) { |
3785 if ( $plugin_data['Version'] ) { |
3786 /* translators: %s: Plugin version */ |
|
2897 $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); |
3787 $status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); |
2898 } |
3788 } |
2899 |
3789 |
2900 if ( ! current_user_can( 'update_plugins' ) ) { |
|
2901 $status['error'] = __( 'You do not have sufficient permissions to update plugins on this site.' ); |
|
2902 wp_send_json_error( $status ); |
|
2903 } |
|
2904 |
|
2905 check_ajax_referer( 'updates' ); |
|
2906 |
|
2907 include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); |
3790 include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); |
2908 |
3791 |
2909 $current = get_site_transient( 'update_plugins' ); |
3792 wp_update_plugins(); |
2910 if ( empty( $current ) ) { |
3793 |
2911 wp_update_plugins(); |
3794 $skin = new WP_Ajax_Upgrader_Skin(); |
2912 } |
3795 $upgrader = new Plugin_Upgrader( $skin ); |
2913 |
3796 $result = $upgrader->bulk_upgrade( array( $plugin ) ); |
2914 $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); |
3797 |
2915 $result = $upgrader->bulk_upgrade( array( $plugin ) ); |
3798 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { |
2916 |
3799 $status['debug'] = $skin->get_upgrade_messages(); |
2917 if ( is_array( $result ) ) { |
3800 } |
3801 |
|
3802 if ( is_wp_error( $skin->result ) ) { |
|
3803 $status['errorCode'] = $skin->result->get_error_code(); |
|
3804 $status['errorMessage'] = $skin->result->get_error_message(); |
|
3805 wp_send_json_error( $status ); |
|
3806 } elseif ( $skin->get_errors()->get_error_code() ) { |
|
3807 $status['errorMessage'] = $skin->get_error_messages(); |
|
3808 wp_send_json_error( $status ); |
|
3809 } elseif ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) { |
|
2918 $plugin_update_data = current( $result ); |
3810 $plugin_update_data = current( $result ); |
2919 |
3811 |
2920 /* |
3812 /* |
2921 * If the `update_plugins` site transient is empty (e.g. when you update |
3813 * If the `update_plugins` site transient is empty (e.g. when you update |
2922 * two plugins in quick succession before the transient repopulates), |
3814 * two plugins in quick succession before the transient repopulates), |
2923 * this may be the return. |
3815 * this may be the return. |
2924 * |
3816 * |
2925 * Preferably something can be done to ensure `update_plugins` isn't empty. |
3817 * Preferably something can be done to ensure `update_plugins` isn't empty. |
2926 * For now, surface some sort of error here. |
3818 * For now, surface some sort of error here. |
2927 */ |
3819 */ |
2928 if ( $plugin_update_data === true ) { |
3820 if ( true === $plugin_update_data ) { |
2929 wp_send_json_error( $status ); |
3821 $status['errorMessage'] = __( 'Plugin update failed.' ); |
2930 } |
3822 wp_send_json_error( $status ); |
2931 |
3823 } |
2932 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
3824 |
3825 $plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] ); |
|
3826 $plugin_data = reset( $plugin_data ); |
|
2933 |
3827 |
2934 if ( $plugin_data['Version'] ) { |
3828 if ( $plugin_data['Version'] ) { |
3829 /* translators: %s: Plugin version */ |
|
2935 $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); |
3830 $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); |
2936 } |
3831 } |
2937 |
|
2938 wp_send_json_success( $status ); |
3832 wp_send_json_success( $status ); |
2939 } else if ( is_wp_error( $result ) ) { |
3833 } elseif ( false === $result ) { |
2940 $status['error'] = $result->get_error_message(); |
3834 global $wp_filesystem; |
2941 wp_send_json_error( $status ); |
3835 |
2942 } else if ( is_bool( $result ) && ! $result ) { |
3836 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
2943 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
3837 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
2944 $status['error'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
3838 |
3839 // Pass through the error from WP_Filesystem if one was raised. |
|
3840 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3841 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3842 } |
|
3843 |
|
2945 wp_send_json_error( $status ); |
3844 wp_send_json_error( $status ); |
2946 } |
3845 } |
2947 } |
3846 |
2948 |
3847 // An unhandled error occurred. |
2949 /** |
3848 $status['errorMessage'] = __( 'Plugin update failed.' ); |
2950 * AJAX handler for saving a post from Press This. |
3849 wp_send_json_error( $status ); |
2951 * |
3850 } |
2952 * @since 4.2.0 |
3851 |
2953 */ |
3852 /** |
2954 function wp_ajax_press_this_save_post() { |
3853 * Ajax handler for deleting a plugin. |
2955 if ( empty( $GLOBALS['wp_press_this'] ) ) { |
3854 * |
2956 include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' ); |
3855 * @since 4.6.0 |
2957 } |
3856 * |
2958 |
3857 * @see delete_plugins() |
2959 $GLOBALS['wp_press_this']->save_post(); |
3858 * |
2960 } |
3859 * @global WP_Filesystem_Base $wp_filesystem Subclass |
2961 |
3860 */ |
2962 /** |
3861 function wp_ajax_delete_plugin() { |
2963 * AJAX handler for creating new category from Press This. |
3862 check_ajax_referer( 'updates' ); |
2964 * |
3863 |
2965 * @since 4.2.0 |
3864 if ( empty( $_POST['slug'] ) || empty( $_POST['plugin'] ) ) { |
2966 */ |
3865 wp_send_json_error( array( |
2967 function wp_ajax_press_this_add_category() { |
3866 'slug' => '', |
2968 if ( empty( $GLOBALS['wp_press_this'] ) ) { |
3867 'errorCode' => 'no_plugin_specified', |
2969 include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' ); |
3868 'errorMessage' => __( 'No plugin specified.' ), |
2970 } |
3869 ) ); |
2971 |
3870 } |
2972 $GLOBALS['wp_press_this']->add_category(); |
3871 |
2973 } |
3872 $plugin = plugin_basename( sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) ); |
3873 |
|
3874 $status = array( |
|
3875 'delete' => 'plugin', |
|
3876 'slug' => sanitize_key( wp_unslash( $_POST['slug'] ) ), |
|
3877 ); |
|
3878 |
|
3879 if ( ! current_user_can( 'delete_plugins' ) || 0 !== validate_file( $plugin ) ) { |
|
3880 $status['errorMessage'] = __( 'Sorry, you are not allowed to delete plugins for this site.' ); |
|
3881 wp_send_json_error( $status ); |
|
3882 } |
|
3883 |
|
3884 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
|
3885 $status['plugin'] = $plugin; |
|
3886 $status['pluginName'] = $plugin_data['Name']; |
|
3887 |
|
3888 if ( is_plugin_active( $plugin ) ) { |
|
3889 $status['errorMessage'] = __( 'You cannot delete a plugin while it is active on the main site.' ); |
|
3890 wp_send_json_error( $status ); |
|
3891 } |
|
3892 |
|
3893 // Check filesystem credentials. `delete_plugins()` will bail otherwise. |
|
3894 $url = wp_nonce_url( 'plugins.php?action=delete-selected&verify-delete=1&checked[]=' . $plugin, 'bulk-plugins' ); |
|
3895 ob_start(); |
|
3896 $credentials = request_filesystem_credentials( $url ); |
|
3897 ob_end_clean(); |
|
3898 if ( false === $credentials || ! WP_Filesystem( $credentials ) ) { |
|
3899 global $wp_filesystem; |
|
3900 |
|
3901 $status['errorCode'] = 'unable_to_connect_to_filesystem'; |
|
3902 $status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' ); |
|
3903 |
|
3904 // Pass through the error from WP_Filesystem if one was raised. |
|
3905 if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) { |
|
3906 $status['errorMessage'] = esc_html( $wp_filesystem->errors->get_error_message() ); |
|
3907 } |
|
3908 |
|
3909 wp_send_json_error( $status ); |
|
3910 } |
|
3911 |
|
3912 $result = delete_plugins( array( $plugin ) ); |
|
3913 |
|
3914 if ( is_wp_error( $result ) ) { |
|
3915 $status['errorMessage'] = $result->get_error_message(); |
|
3916 wp_send_json_error( $status ); |
|
3917 } elseif ( false === $result ) { |
|
3918 $status['errorMessage'] = __( 'Plugin could not be deleted.' ); |
|
3919 wp_send_json_error( $status ); |
|
3920 } |
|
3921 |
|
3922 wp_send_json_success( $status ); |
|
3923 } |
|
3924 |
|
3925 /** |
|
3926 * Ajax handler for searching plugins. |
|
3927 * |
|
3928 * @since 4.6.0 |
|
3929 * |
|
3930 * @global string $s Search term. |
|
3931 */ |
|
3932 function wp_ajax_search_plugins() { |
|
3933 check_ajax_referer( 'updates' ); |
|
3934 |
|
3935 $pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : ''; |
|
3936 if ( 'plugins-network' === $pagenow || 'plugins' === $pagenow ) { |
|
3937 set_current_screen( $pagenow ); |
|
3938 } |
|
3939 |
|
3940 /** @var WP_Plugins_List_Table $wp_list_table */ |
|
3941 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table', array( |
|
3942 'screen' => get_current_screen(), |
|
3943 ) ); |
|
3944 |
|
3945 $status = array(); |
|
3946 |
|
3947 if ( ! $wp_list_table->ajax_user_can() ) { |
|
3948 $status['errorMessage'] = __( 'Sorry, you are not allowed to manage plugins for this site.' ); |
|
3949 wp_send_json_error( $status ); |
|
3950 } |
|
3951 |
|
3952 // Set the correct requester, so pagination works. |
|
3953 $_SERVER['REQUEST_URI'] = add_query_arg( array_diff_key( $_POST, array( |
|
3954 '_ajax_nonce' => null, |
|
3955 'action' => null, |
|
3956 ) ), network_admin_url( 'plugins.php', 'relative' ) ); |
|
3957 |
|
3958 $GLOBALS['s'] = wp_unslash( $_POST['s'] ); |
|
3959 |
|
3960 $wp_list_table->prepare_items(); |
|
3961 |
|
3962 ob_start(); |
|
3963 $wp_list_table->display(); |
|
3964 $status['count'] = count( $wp_list_table->items ); |
|
3965 $status['items'] = ob_get_clean(); |
|
3966 |
|
3967 wp_send_json_success( $status ); |
|
3968 } |
|
3969 |
|
3970 /** |
|
3971 * Ajax handler for searching plugins to install. |
|
3972 * |
|
3973 * @since 4.6.0 |
|
3974 */ |
|
3975 function wp_ajax_search_install_plugins() { |
|
3976 check_ajax_referer( 'updates' ); |
|
3977 |
|
3978 $pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : ''; |
|
3979 if ( 'plugin-install-network' === $pagenow || 'plugin-install' === $pagenow ) { |
|
3980 set_current_screen( $pagenow ); |
|
3981 } |
|
3982 |
|
3983 /** @var WP_Plugin_Install_List_Table $wp_list_table */ |
|
3984 $wp_list_table = _get_list_table( 'WP_Plugin_Install_List_Table', array( |
|
3985 'screen' => get_current_screen(), |
|
3986 ) ); |
|
3987 |
|
3988 $status = array(); |
|
3989 |
|
3990 if ( ! $wp_list_table->ajax_user_can() ) { |
|
3991 $status['errorMessage'] = __( 'Sorry, you are not allowed to manage plugins for this site.' ); |
|
3992 wp_send_json_error( $status ); |
|
3993 } |
|
3994 |
|
3995 // Set the correct requester, so pagination works. |
|
3996 $_SERVER['REQUEST_URI'] = add_query_arg( array_diff_key( $_POST, array( |
|
3997 '_ajax_nonce' => null, |
|
3998 'action' => null, |
|
3999 ) ), network_admin_url( 'plugin-install.php', 'relative' ) ); |
|
4000 |
|
4001 $wp_list_table->prepare_items(); |
|
4002 |
|
4003 ob_start(); |
|
4004 $wp_list_table->display(); |
|
4005 $status['count'] = (int) $wp_list_table->get_pagination_arg( 'total_items' ); |
|
4006 $status['items'] = ob_get_clean(); |
|
4007 |
|
4008 wp_send_json_success( $status ); |
|
4009 } |
|
4010 |
|
4011 /** |
|
4012 * Ajax handler for editing a theme or plugin file. |
|
4013 * |
|
4014 * @since 4.9.0 |
|
4015 * @see wp_edit_theme_plugin_file() |
|
4016 */ |
|
4017 function wp_ajax_edit_theme_plugin_file() { |
|
4018 $r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) ); // Validation of args is done in wp_edit_theme_plugin_file(). |
|
4019 if ( is_wp_error( $r ) ) { |
|
4020 wp_send_json_error( array_merge( |
|
4021 array( |
|
4022 'code' => $r->get_error_code(), |
|
4023 'message' => $r->get_error_message(), |
|
4024 ), |
|
4025 (array) $r->get_error_data() |
|
4026 ) ); |
|
4027 } else { |
|
4028 wp_send_json_success( array( |
|
4029 'message' => __( 'File edited successfully.' ), |
|
4030 ) ); |
|
4031 } |
|
4032 } |
|
4033 |
|
4034 /** |
|
4035 * Ajax handler for exporting a user's personal data. |
|
4036 * |
|
4037 * @since 4.9.6 |
|
4038 */ |
|
4039 function wp_ajax_wp_privacy_export_personal_data() { |
|
4040 |
|
4041 if ( empty( $_POST['id'] ) ) { |
|
4042 wp_send_json_error( __( 'Missing request ID.' ) ); |
|
4043 } |
|
4044 $request_id = (int) $_POST['id']; |
|
4045 |
|
4046 if ( $request_id < 1 ) { |
|
4047 wp_send_json_error( __( 'Invalid request ID.' ) ); |
|
4048 } |
|
4049 |
|
4050 if ( ! current_user_can( 'export_others_personal_data' ) ) { |
|
4051 wp_send_json_error( __( 'Invalid request.' ) ); |
|
4052 } |
|
4053 |
|
4054 check_ajax_referer( 'wp-privacy-export-personal-data-' . $request_id, 'security' ); |
|
4055 |
|
4056 // Get the request data. |
|
4057 $request = wp_get_user_request_data( $request_id ); |
|
4058 |
|
4059 if ( ! $request || 'export_personal_data' !== $request->action_name ) { |
|
4060 wp_send_json_error( __( 'Invalid request type.' ) ); |
|
4061 } |
|
4062 |
|
4063 $email_address = $request->email; |
|
4064 if ( ! is_email( $email_address ) ) { |
|
4065 wp_send_json_error( __( 'A valid email address must be given.' ) ); |
|
4066 } |
|
4067 |
|
4068 if ( ! isset( $_POST['exporter'] ) ) { |
|
4069 wp_send_json_error( __( 'Missing exporter index.' ) ); |
|
4070 } |
|
4071 $exporter_index = (int) $_POST['exporter']; |
|
4072 |
|
4073 if ( ! isset( $_POST['page'] ) ) { |
|
4074 wp_send_json_error( __( 'Missing page index.' ) ); |
|
4075 } |
|
4076 $page = (int) $_POST['page']; |
|
4077 |
|
4078 $send_as_email = isset( $_POST['sendAsEmail'] ) ? ( 'true' === $_POST['sendAsEmail'] ) : false; |
|
4079 |
|
4080 /** |
|
4081 * Filters the array of exporter callbacks. |
|
4082 * |
|
4083 * @since 4.9.6 |
|
4084 * |
|
4085 * @param array $args { |
|
4086 * An array of callable exporters of personal data. Default empty array. |
|
4087 * |
|
4088 * @type array { |
|
4089 * Array of personal data exporters. |
|
4090 * |
|
4091 * @type string $callback Callable exporter function that accepts an |
|
4092 * email address and a page and returns an array |
|
4093 * of name => value pairs of personal data. |
|
4094 * @type string $exporter_friendly_name Translated user facing friendly name for the |
|
4095 * exporter. |
|
4096 * } |
|
4097 * } |
|
4098 */ |
|
4099 $exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() ); |
|
4100 |
|
4101 if ( ! is_array( $exporters ) ) { |
|
4102 wp_send_json_error( __( 'An exporter has improperly used the registration filter.' ) ); |
|
4103 } |
|
4104 |
|
4105 // Do we have any registered exporters? |
|
4106 if ( 0 < count( $exporters ) ) { |
|
4107 if ( $exporter_index < 1 ) { |
|
4108 wp_send_json_error( __( 'Exporter index cannot be negative.' ) ); |
|
4109 } |
|
4110 |
|
4111 if ( $exporter_index > count( $exporters ) ) { |
|
4112 wp_send_json_error( __( 'Exporter index out of range.' ) ); |
|
4113 } |
|
4114 |
|
4115 if ( $page < 1 ) { |
|
4116 wp_send_json_error( __( 'Page index cannot be less than one.' ) ); |
|
4117 } |
|
4118 |
|
4119 $exporter_keys = array_keys( $exporters ); |
|
4120 $exporter_key = $exporter_keys[ $exporter_index - 1 ]; |
|
4121 $exporter = $exporters[ $exporter_key ]; |
|
4122 |
|
4123 if ( ! is_array( $exporter ) ) { |
|
4124 wp_send_json_error( |
|
4125 /* translators: %s: array index */ |
|
4126 sprintf( __( 'Expected an array describing the exporter at index %s.' ), $exporter_key ) |
|
4127 ); |
|
4128 } |
|
4129 if ( ! array_key_exists( 'exporter_friendly_name', $exporter ) ) { |
|
4130 wp_send_json_error( |
|
4131 /* translators: %s: array index */ |
|
4132 sprintf( __( 'Exporter array at index %s does not include a friendly name.' ), $exporter_key ) |
|
4133 ); |
|
4134 } |
|
4135 if ( ! array_key_exists( 'callback', $exporter ) ) { |
|
4136 wp_send_json_error( |
|
4137 /* translators: %s: exporter friendly name */ |
|
4138 sprintf( __( 'Exporter does not include a callback: %s.' ), esc_html( $exporter['exporter_friendly_name'] ) ) |
|
4139 ); |
|
4140 } |
|
4141 if ( ! is_callable( $exporter['callback'] ) ) { |
|
4142 wp_send_json_error( |
|
4143 /* translators: %s: exporter friendly name */ |
|
4144 sprintf( __( 'Exporter callback is not a valid callback: %s.' ), esc_html( $exporter['exporter_friendly_name'] ) ) |
|
4145 ); |
|
4146 } |
|
4147 |
|
4148 $callback = $exporter['callback']; |
|
4149 $exporter_friendly_name = $exporter['exporter_friendly_name']; |
|
4150 |
|
4151 $response = call_user_func( $callback, $email_address, $page ); |
|
4152 if ( is_wp_error( $response ) ) { |
|
4153 wp_send_json_error( $response ); |
|
4154 } |
|
4155 |
|
4156 if ( ! is_array( $response ) ) { |
|
4157 wp_send_json_error( |
|
4158 /* translators: %s: exporter friendly name */ |
|
4159 sprintf( __( 'Expected response as an array from exporter: %s.' ), esc_html( $exporter_friendly_name ) ) |
|
4160 ); |
|
4161 } |
|
4162 if ( ! array_key_exists( 'data', $response ) ) { |
|
4163 wp_send_json_error( |
|
4164 /* translators: %s: exporter friendly name */ |
|
4165 sprintf( __( 'Expected data in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) ) |
|
4166 ); |
|
4167 } |
|
4168 if ( ! is_array( $response['data'] ) ) { |
|
4169 wp_send_json_error( |
|
4170 /* translators: %s: exporter friendly name */ |
|
4171 sprintf( __( 'Expected data array in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) ) |
|
4172 ); |
|
4173 } |
|
4174 if ( ! array_key_exists( 'done', $response ) ) { |
|
4175 wp_send_json_error( |
|
4176 /* translators: %s: exporter friendly name */ |
|
4177 sprintf( __( 'Expected done (boolean) in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) ) |
|
4178 ); |
|
4179 } |
|
4180 } else { |
|
4181 // No exporters, so we're done. |
|
4182 $exporter_key = ''; |
|
4183 |
|
4184 $response = array( |
|
4185 'data' => array(), |
|
4186 'done' => true, |
|
4187 ); |
|
4188 } |
|
4189 |
|
4190 /** |
|
4191 * Filters a page of personal data exporter data. Used to build the export report. |
|
4192 * |
|
4193 * Allows the export response to be consumed by destinations in addition to Ajax. |
|
4194 * |
|
4195 * @since 4.9.6 |
|
4196 * |
|
4197 * @param array $response The personal data for the given exporter and page. |
|
4198 * @param int $exporter_index The index of the exporter that provided this data. |
|
4199 * @param string $email_address The email address associated with this personal data. |
|
4200 * @param int $page The page for this response. |
|
4201 * @param int $request_id The privacy request post ID associated with this request. |
|
4202 * @param bool $send_as_email Whether the final results of the export should be emailed to the user. |
|
4203 * @param string $exporter_key The key (slug) of the exporter that provided this data. |
|
4204 */ |
|
4205 $response = apply_filters( 'wp_privacy_personal_data_export_page', $response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key ); |
|
4206 |
|
4207 if ( is_wp_error( $response ) ) { |
|
4208 wp_send_json_error( $response ); |
|
4209 } |
|
4210 |
|
4211 wp_send_json_success( $response ); |
|
4212 } |
|
4213 |
|
4214 /** |
|
4215 * Ajax handler for erasing personal data. |
|
4216 * |
|
4217 * @since 4.9.6 |
|
4218 */ |
|
4219 function wp_ajax_wp_privacy_erase_personal_data() { |
|
4220 |
|
4221 if ( empty( $_POST['id'] ) ) { |
|
4222 wp_send_json_error( __( 'Missing request ID.' ) ); |
|
4223 } |
|
4224 |
|
4225 $request_id = (int) $_POST['id']; |
|
4226 |
|
4227 if ( $request_id < 1 ) { |
|
4228 wp_send_json_error( __( 'Invalid request ID.' ) ); |
|
4229 } |
|
4230 |
|
4231 // Both capabilities are required to avoid confusion, see `_wp_personal_data_removal_page()`. |
|
4232 if ( ! current_user_can( 'erase_others_personal_data' ) || ! current_user_can( 'delete_users' ) ) { |
|
4233 wp_send_json_error( __( 'Invalid request.' ) ); |
|
4234 } |
|
4235 |
|
4236 check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' ); |
|
4237 |
|
4238 // Get the request data. |
|
4239 $request = wp_get_user_request_data( $request_id ); |
|
4240 |
|
4241 if ( ! $request || 'remove_personal_data' !== $request->action_name ) { |
|
4242 wp_send_json_error( __( 'Invalid request ID.' ) ); |
|
4243 } |
|
4244 |
|
4245 $email_address = $request->email; |
|
4246 |
|
4247 if ( ! is_email( $email_address ) ) { |
|
4248 wp_send_json_error( __( 'Invalid email address in request.' ) ); |
|
4249 } |
|
4250 |
|
4251 if ( ! isset( $_POST['eraser'] ) ) { |
|
4252 wp_send_json_error( __( 'Missing eraser index.' ) ); |
|
4253 } |
|
4254 |
|
4255 $eraser_index = (int) $_POST['eraser']; |
|
4256 |
|
4257 if ( ! isset( $_POST['page'] ) ) { |
|
4258 wp_send_json_error( __( 'Missing page index.' ) ); |
|
4259 } |
|
4260 |
|
4261 $page = (int) $_POST['page']; |
|
4262 |
|
4263 /** |
|
4264 * Filters the array of personal data eraser callbacks. |
|
4265 * |
|
4266 * @since 4.9.6 |
|
4267 * |
|
4268 * @param array $args { |
|
4269 * An array of callable erasers of personal data. Default empty array. |
|
4270 * |
|
4271 * @type array { |
|
4272 * Array of personal data exporters. |
|
4273 * |
|
4274 * @type string $callback Callable eraser that accepts an email address and |
|
4275 * a page and returns an array with boolean values for |
|
4276 * whether items were removed or retained and any messages |
|
4277 * from the eraser, as well as if additional pages are |
|
4278 * available. |
|
4279 * @type string $exporter_friendly_name Translated user facing friendly name for the eraser. |
|
4280 * } |
|
4281 * } |
|
4282 */ |
|
4283 $erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() ); |
|
4284 |
|
4285 // Do we have any registered erasers? |
|
4286 if ( 0 < count( $erasers ) ) { |
|
4287 |
|
4288 if ( $eraser_index < 1 ) { |
|
4289 wp_send_json_error( __( 'Eraser index cannot be less than one.' ) ); |
|
4290 } |
|
4291 |
|
4292 if ( $eraser_index > count( $erasers ) ) { |
|
4293 wp_send_json_error( __( 'Eraser index is out of range.' ) ); |
|
4294 } |
|
4295 |
|
4296 if ( $page < 1 ) { |
|
4297 wp_send_json_error( __( 'Page index cannot be less than one.' ) ); |
|
4298 } |
|
4299 |
|
4300 $eraser_keys = array_keys( $erasers ); |
|
4301 $eraser_key = $eraser_keys[ $eraser_index - 1 ]; |
|
4302 $eraser = $erasers[ $eraser_key ]; |
|
4303 |
|
4304 if ( ! is_array( $eraser ) ) { |
|
4305 /* translators: %d: array index */ |
|
4306 wp_send_json_error( sprintf( __( 'Expected an array describing the eraser at index %d.' ), $eraser_index ) ); |
|
4307 } |
|
4308 |
|
4309 if ( ! array_key_exists( 'callback', $eraser ) ) { |
|
4310 /* translators: %d: array index */ |
|
4311 wp_send_json_error( sprintf( __( 'Eraser array at index %d does not include a callback.' ), $eraser_index ) ); |
|
4312 } |
|
4313 |
|
4314 if ( ! is_callable( $eraser['callback'] ) ) { |
|
4315 /* translators: %d: array index */ |
|
4316 wp_send_json_error( sprintf( __( 'Eraser callback at index %d is not a valid callback.' ), $eraser_index ) ); |
|
4317 } |
|
4318 |
|
4319 if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) { |
|
4320 /* translators: %d: array index */ |
|
4321 wp_send_json_error( sprintf( __( 'Eraser array at index %d does not include a friendly name.' ), $eraser_index ) ); |
|
4322 } |
|
4323 |
|
4324 $callback = $eraser['callback']; |
|
4325 $eraser_friendly_name = $eraser['eraser_friendly_name']; |
|
4326 |
|
4327 $response = call_user_func( $callback, $email_address, $page ); |
|
4328 |
|
4329 if ( is_wp_error( $response ) ) { |
|
4330 wp_send_json_error( $response ); |
|
4331 } |
|
4332 |
|
4333 if ( ! is_array( $response ) ) { |
|
4334 wp_send_json_error( |
|
4335 sprintf( |
|
4336 /* translators: 1: eraser friendly name, 2: array index */ |
|
4337 __( 'Did not receive array from %1$s eraser (index %2$d).' ), |
|
4338 esc_html( $eraser_friendly_name ), |
|
4339 $eraser_index |
|
4340 ) |
|
4341 ); |
|
4342 } |
|
4343 |
|
4344 if ( ! array_key_exists( 'items_removed', $response ) ) { |
|
4345 wp_send_json_error( |
|
4346 sprintf( |
|
4347 /* translators: 1: eraser friendly name, 2: array index */ |
|
4348 __( 'Expected items_removed key in response array from %1$s eraser (index %2$d).' ), |
|
4349 esc_html( $eraser_friendly_name ), |
|
4350 $eraser_index |
|
4351 ) |
|
4352 ); |
|
4353 } |
|
4354 |
|
4355 if ( ! array_key_exists( 'items_retained', $response ) ) { |
|
4356 wp_send_json_error( |
|
4357 sprintf( |
|
4358 /* translators: 1: eraser friendly name, 2: array index */ |
|
4359 __( 'Expected items_retained key in response array from %1$s eraser (index %2$d).' ), |
|
4360 esc_html( $eraser_friendly_name ), |
|
4361 $eraser_index |
|
4362 ) |
|
4363 ); |
|
4364 } |
|
4365 |
|
4366 if ( ! array_key_exists( 'messages', $response ) ) { |
|
4367 wp_send_json_error( |
|
4368 sprintf( |
|
4369 /* translators: 1: eraser friendly name, 2: array index */ |
|
4370 __( 'Expected messages key in response array from %1$s eraser (index %2$d).' ), |
|
4371 esc_html( $eraser_friendly_name ), |
|
4372 $eraser_index |
|
4373 ) |
|
4374 ); |
|
4375 } |
|
4376 |
|
4377 if ( ! is_array( $response['messages'] ) ) { |
|
4378 wp_send_json_error( |
|
4379 sprintf( |
|
4380 /* translators: 1: eraser friendly name, 2: array index */ |
|
4381 __( 'Expected messages key to reference an array in response array from %1$s eraser (index %2$d).' ), |
|
4382 esc_html( $eraser_friendly_name ), |
|
4383 $eraser_index |
|
4384 ) |
|
4385 ); |
|
4386 } |
|
4387 |
|
4388 if ( ! array_key_exists( 'done', $response ) ) { |
|
4389 wp_send_json_error( |
|
4390 sprintf( |
|
4391 /* translators: 1: eraser friendly name, 2: array index */ |
|
4392 __( 'Expected done flag in response array from %1$s eraser (index %2$d).' ), |
|
4393 esc_html( $eraser_friendly_name ), |
|
4394 $eraser_index |
|
4395 ) |
|
4396 ); |
|
4397 } |
|
4398 } else { |
|
4399 // No erasers, so we're done. |
|
4400 $eraser_key = ''; |
|
4401 |
|
4402 $response = array( |
|
4403 'items_removed' => false, |
|
4404 'items_retained' => false, |
|
4405 'messages' => array(), |
|
4406 'done' => true, |
|
4407 ); |
|
4408 } |
|
4409 |
|
4410 /** |
|
4411 * Filters a page of personal data eraser data. |
|
4412 * |
|
4413 * Allows the erasure response to be consumed by destinations in addition to Ajax. |
|
4414 * |
|
4415 * @since 4.9.6 |
|
4416 * |
|
4417 * @param array $response The personal data for the given exporter and page. |
|
4418 * @param int $eraser_index The index of the eraser that provided this data. |
|
4419 * @param string $email_address The email address associated with this personal data. |
|
4420 * @param int $page The page for this response. |
|
4421 * @param int $request_id The privacy request post ID associated with this request. |
|
4422 * @param string $eraser_key The key (slug) of the eraser that provided this data. |
|
4423 */ |
|
4424 $response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id, $eraser_key ); |
|
4425 |
|
4426 if ( is_wp_error( $response ) ) { |
|
4427 wp_send_json_error( $response ); |
|
4428 } |
|
4429 |
|
4430 wp_send_json_success( $response ); |
|
4431 } |