/wp-admin/includes/ajax-actions.php
PHP | 1650 lines | 1223 code | 310 blank | 117 comment | 353 complexity | d6c5c59e8355b1511a2a2cc9e6ba5719 MD5 | raw file
1<?php
2/**
3 * WordPress Core Ajax Handlers.
4 *
5 * @package WordPress
6 * @subpackage Administration
7 */
8
9/*
10 * No-privilege Ajax handlers.
11 */
12
13/**
14 * Heartbeat API (experimental)
15 *
16 * Runs when the user is not logged in.
17 */
18function wp_ajax_nopriv_heartbeat() {
19 $response = array();
20
21 // screen_id is the same as $current_screen->id and the JS global 'pagenow'
22 if ( ! empty($_POST['screen_id']) )
23 $screen_id = sanitize_key($_POST['screen_id']);
24 else
25 $screen_id = 'front';
26
27 if ( ! empty($_POST['data']) ) {
28 $data = wp_unslash( (array) $_POST['data'] );
29
30 /**
31 * Filter Heartbeat AJAX response in no-privilege environments.
32 *
33 * @since 3.6.0
34 *
35 * @param array|object $response The no-priv Heartbeat response object or array.
36 * @param array $data An array of data passed via $_POST.
37 * @param string $screen_id The screen id.
38 */
39 $response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id );
40 }
41
42 /**
43 * Filter Heartbeat AJAX response when no data is passed.
44 *
45 * @since 3.6.0
46 *
47 * @param array|object $response The Heartbeat response object or array.
48 * @param string $screen_id The screen id.
49 */
50 $response = apply_filters( 'heartbeat_nopriv_send', $response, $screen_id );
51
52 /**
53 * Fires when Heartbeat ticks in no-privilege environments.
54 *
55 * Allows the transport to be easily replaced with long-polling.
56 *
57 * @since 3.6.0
58 *
59 * @param array|object $response The no-priv Heartbeat response.
60 * @param string $screen_id The screen id.
61 */
62 do_action( 'heartbeat_nopriv_tick', $response, $screen_id );
63
64 // send the current time according to the server
65 $response['server_time'] = time();
66
67 wp_send_json($response);
68}
69
70/*
71 * GET-based Ajax handlers.
72 */
73function wp_ajax_fetch_list() {
74 global $wp_list_table;
75
76 $list_class = $_GET['list_args']['class'];
77 check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' );
78
79 $wp_list_table = _get_list_table( $list_class, array( 'screen' => $_GET['list_args']['screen']['id'] ) );
80 if ( ! $wp_list_table )
81 wp_die( 0 );
82
83 if ( ! $wp_list_table->ajax_user_can() )
84 wp_die( -1 );
85
86 $wp_list_table->ajax_response();
87
88 wp_die( 0 );
89}
90function wp_ajax_ajax_tag_search() {
91 global $wpdb;
92
93 if ( isset( $_GET['tax'] ) ) {
94 $taxonomy = sanitize_key( $_GET['tax'] );
95 $tax = get_taxonomy( $taxonomy );
96 if ( ! $tax )
97 wp_die( 0 );
98 if ( ! current_user_can( $tax->cap->assign_terms ) )
99 wp_die( -1 );
100 } else {
101 wp_die( 0 );
102 }
103
104 $s = wp_unslash( $_GET['q'] );
105
106 $comma = _x( ',', 'tag delimiter' );
107 if ( ',' !== $comma )
108 $s = str_replace( $comma, ',', $s );
109 if ( false !== strpos( $s, ',' ) ) {
110 $s = explode( ',', $s );
111 $s = $s[count( $s ) - 1];
112 }
113 $s = trim( $s );
114 if ( strlen( $s ) < 2 )
115 wp_die(); // require 2 chars for matching
116
117 $results = get_terms( $taxonomy, array( 'name__like' => $s, 'fields' => 'names', 'hide_empty' => false ) );
118
119 echo join( $results, "\n" );
120 wp_die();
121}
122
123function wp_ajax_wp_compression_test() {
124 if ( !current_user_can( 'manage_options' ) )
125 wp_die( -1 );
126
127 if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) {
128 update_site_option('can_compress_scripts', 0);
129 wp_die( 0 );
130 }
131
132 if ( isset($_GET['test']) ) {
133 header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
134 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
135 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
136 header( 'Pragma: no-cache' );
137 header('Content-Type: application/x-javascript; charset=UTF-8');
138 $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP );
139 $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."';
140
141 if ( 1 == $_GET['test'] ) {
142 echo $test_str;
143 wp_die();
144 } elseif ( 2 == $_GET['test'] ) {
145 if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
146 wp_die( -1 );
147 if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && ! $force_gzip ) {
148 header('Content-Encoding: deflate');
149 $out = gzdeflate( $test_str, 1 );
150 } elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) {
151 header('Content-Encoding: gzip');
152 $out = gzencode( $test_str, 1 );
153 } else {
154 wp_die( -1 );
155 }
156 echo $out;
157 wp_die();
158 } elseif ( 'no' == $_GET['test'] ) {
159 update_site_option('can_compress_scripts', 0);
160 } elseif ( 'yes' == $_GET['test'] ) {
161 update_site_option('can_compress_scripts', 1);
162 }
163 }
164
165 wp_die( 0 );
166}
167
168function wp_ajax_imgedit_preview() {
169 $post_id = intval($_GET['postid']);
170 if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
171 wp_die( -1 );
172
173 check_ajax_referer( "image_editor-$post_id" );
174
175 include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
176 if ( ! stream_preview_image($post_id) )
177 wp_die( -1 );
178
179 wp_die();
180}
181
182function wp_ajax_oembed_cache() {
183 global $wp_embed;
184
185 $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
186 wp_die( $return );
187}
188
189function wp_ajax_autocomplete_user() {
190 if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) )
191 wp_die( -1 );
192
193 /** This filter is documented in wp-admin/user-new.php */
194 if ( ! is_super_admin() && ! apply_filters( 'autocomplete_users_for_site_admins', false ) )
195 wp_die( -1 );
196
197 $return = array();
198
199 // Check the type of request
200 if ( isset( $_REQUEST['autocomplete_type'] ) )
201 $type = $_REQUEST['autocomplete_type'];
202 else
203 $type = 'add';
204
205 // Exclude current users of this blog
206 if ( isset( $_REQUEST['site_id'] ) )
207 $id = absint( $_REQUEST['site_id'] );
208 else
209 $id = get_current_blog_id();
210
211 $include_blog_users = ( $type == 'search' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
212 $exclude_blog_users = ( $type == 'add' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
213
214 $users = get_users( array(
215 'blog_id' => false,
216 'search' => '*' . $_REQUEST['term'] . '*',
217 'include' => $include_blog_users,
218 'exclude' => $exclude_blog_users,
219 'search_columns' => array( 'user_login', 'user_nicename', 'user_email' ),
220 ) );
221
222 foreach ( $users as $user ) {
223 $return[] = array(
224 /* translators: 1: user_login, 2: user_email */
225 'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
226 'value' => $user->user_login,
227 );
228 }
229
230 wp_die( json_encode( $return ) );
231}
232
233function wp_ajax_dashboard_widgets() {
234 require_once ABSPATH . 'wp-admin/includes/dashboard.php';
235
236 $pagenow = $_GET['pagenow'];
237 if ( $pagenow === 'dashboard-user' || $pagenow === 'dashboard-network' || $pagenow === 'dashboard' ) {
238 set_current_screen( $pagenow );
239 }
240
241 switch ( $_GET['widget'] ) {
242 case 'dashboard_primary' :
243 wp_dashboard_primary();
244 break;
245 }
246 wp_die();
247}
248
249function wp_ajax_logged_in() {
250 wp_die( 1 );
251}
252
253/*
254 * Ajax helper.
255 */
256
257/**
258 * Sends back current comment total and new page links if they need to be updated.
259 *
260 * Contrary to normal success AJAX response ("1"), die with time() on success.
261 *
262 * @since 2.7
263 *
264 * @param int $comment_id
265 * @return die
266 */
267function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
268 $total = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0;
269 $per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
270 $page = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0;
271 $url = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : '';
272
273 // JS didn't send us everything we need to know. Just die with success message
274 if ( !$total || !$per_page || !$page || !$url )
275 wp_die( time() );
276
277 $total += $delta;
278 if ( $total < 0 )
279 $total = 0;
280
281 // Only do the expensive stuff on a page-break, and about 1 other time per page
282 if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
283 $post_id = 0;
284 $status = 'total_comments'; // What type of comment count are we looking for?
285 $parsed = parse_url( $url );
286 if ( isset( $parsed['query'] ) ) {
287 parse_str( $parsed['query'], $query_vars );
288 if ( !empty( $query_vars['comment_status'] ) )
289 $status = $query_vars['comment_status'];
290 if ( !empty( $query_vars['p'] ) )
291 $post_id = (int) $query_vars['p'];
292 }
293
294 $comment_count = wp_count_comments($post_id);
295
296 if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count
297 $total = $comment_count->$status;
298 // else use the decremented value from above
299 }
300
301 $time = time(); // The time since the last comment count
302
303 $x = new WP_Ajax_Response( array(
304 'what' => 'comment',
305 'id' => $comment_id, // here for completeness - not used
306 'supplemental' => array(
307 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
308 'total_pages' => ceil( $total / $per_page ),
309 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
310 'total' => $total,
311 'time' => $time
312 )
313 ) );
314 $x->send();
315}
316
317/*
318 * POST-based Ajax handlers.
319 */
320
321function _wp_ajax_add_hierarchical_term() {
322 $action = $_POST['action'];
323 $taxonomy = get_taxonomy(substr($action, 4));
324 check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
325 if ( !current_user_can( $taxonomy->cap->edit_terms ) )
326 wp_die( -1 );
327 $names = explode(',', $_POST['new'.$taxonomy->name]);
328 $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
329 if ( 0 > $parent )
330 $parent = 0;
331 if ( $taxonomy->name == 'category' )
332 $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
333 else
334 $post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array();
335 $checked_categories = array_map( 'absint', (array) $post_category );
336 $popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false);
337
338 foreach ( $names as $cat_name ) {
339 $cat_name = trim($cat_name);
340 $category_nicename = sanitize_title($cat_name);
341 if ( '' === $category_nicename )
342 continue;
343 if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) )
344 $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
345 if ( is_wp_error( $cat_id ) )
346 continue;
347 else if ( is_array( $cat_id ) )
348 $cat_id = $cat_id['term_id'];
349 $checked_categories[] = $cat_id;
350 if ( $parent ) // Do these all at once in a second
351 continue;
352 ob_start();
353 wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids ));
354 $data = ob_get_contents();
355 ob_end_clean();
356 $add = array(
357 'what' => $taxonomy->name,
358 'id' => $cat_id,
359 'data' => str_replace( array("\n", "\t"), '', $data),
360 'position' => -1
361 );
362 }
363
364 if ( $parent ) { // Foncy - replace the parent and all its children
365 $parent = get_term( $parent, $taxonomy->name );
366 $term_id = $parent->term_id;
367
368 while ( $parent->parent ) { // get the top parent
369 $parent = get_term( $parent->parent, $taxonomy->name );
370 if ( is_wp_error( $parent ) )
371 break;
372 $term_id = $parent->term_id;
373 }
374
375 ob_start();
376 wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids));
377 $data = ob_get_contents();
378 ob_end_clean();
379 $add = array(
380 'what' => $taxonomy->name,
381 'id' => $term_id,
382 'data' => str_replace( array("\n", "\t"), '', $data),
383 'position' => -1
384 );
385 }
386
387 ob_start();
388 wp_dropdown_categories( array(
389 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name',
390 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —'
391 ) );
392 $sup = ob_get_contents();
393 ob_end_clean();
394 $add['supplemental'] = array( 'newcat_parent' => $sup );
395
396 $x = new WP_Ajax_Response( $add );
397 $x->send();
398}
399
400function wp_ajax_delete_comment() {
401 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
402
403 if ( !$comment = get_comment( $id ) )
404 wp_die( time() );
405 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
406 wp_die( -1 );
407
408 check_ajax_referer( "delete-comment_$id" );
409 $status = wp_get_comment_status( $comment->comment_ID );
410
411 $delta = -1;
412 if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
413 if ( 'trash' == $status )
414 wp_die( time() );
415 $r = wp_trash_comment( $comment->comment_ID );
416 } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
417 if ( 'trash' != $status )
418 wp_die( time() );
419 $r = wp_untrash_comment( $comment->comment_ID );
420 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
421 $delta = 1;
422 } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
423 if ( 'spam' == $status )
424 wp_die( time() );
425 $r = wp_spam_comment( $comment->comment_ID );
426 } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
427 if ( 'spam' != $status )
428 wp_die( time() );
429 $r = wp_unspam_comment( $comment->comment_ID );
430 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
431 $delta = 1;
432 } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
433 $r = wp_delete_comment( $comment->comment_ID );
434 } else {
435 wp_die( -1 );
436 }
437
438 if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts
439 _wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
440 wp_die( 0 );
441}
442
443function wp_ajax_delete_tag() {
444 $tag_id = (int) $_POST['tag_ID'];
445 check_ajax_referer( "delete-tag_$tag_id" );
446
447 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
448 $tax = get_taxonomy($taxonomy);
449
450 if ( !current_user_can( $tax->cap->delete_terms ) )
451 wp_die( -1 );
452
453 $tag = get_term( $tag_id, $taxonomy );
454 if ( !$tag || is_wp_error( $tag ) )
455 wp_die( 1 );
456
457 if ( wp_delete_term($tag_id, $taxonomy))
458 wp_die( 1 );
459 else
460 wp_die( 0 );
461}
462
463function wp_ajax_delete_link() {
464 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
465
466 check_ajax_referer( "delete-bookmark_$id" );
467 if ( !current_user_can( 'manage_links' ) )
468 wp_die( -1 );
469
470 $link = get_bookmark( $id );
471 if ( !$link || is_wp_error( $link ) )
472 wp_die( 1 );
473
474 if ( wp_delete_link( $id ) )
475 wp_die( 1 );
476 else
477 wp_die( 0 );
478}
479
480function wp_ajax_delete_meta() {
481 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
482
483 check_ajax_referer( "delete-meta_$id" );
484 if ( !$meta = get_metadata_by_mid( 'post', $id ) )
485 wp_die( 1 );
486
487 if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $meta->post_id, $meta->meta_key ) )
488 wp_die( -1 );
489 if ( delete_meta( $meta->meta_id ) )
490 wp_die( 1 );
491 wp_die( 0 );
492}
493
494function wp_ajax_delete_post( $action ) {
495 if ( empty( $action ) )
496 $action = 'delete-post';
497 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
498
499 check_ajax_referer( "{$action}_$id" );
500 if ( !current_user_can( 'delete_post', $id ) )
501 wp_die( -1 );
502
503 if ( !get_post( $id ) )
504 wp_die( 1 );
505
506 if ( wp_delete_post( $id ) )
507 wp_die( 1 );
508 else
509 wp_die( 0 );
510}
511
512function wp_ajax_trash_post( $action ) {
513 if ( empty( $action ) )
514 $action = 'trash-post';
515 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
516
517 check_ajax_referer( "{$action}_$id" );
518 if ( !current_user_can( 'delete_post', $id ) )
519 wp_die( -1 );
520
521 if ( !get_post( $id ) )
522 wp_die( 1 );
523
524 if ( 'trash-post' == $action )
525 $done = wp_trash_post( $id );
526 else
527 $done = wp_untrash_post( $id );
528
529 if ( $done )
530 wp_die( 1 );
531
532 wp_die( 0 );
533}
534
535function wp_ajax_untrash_post( $action ) {
536 if ( empty( $action ) )
537 $action = 'untrash-post';
538 wp_ajax_trash_post( $action );
539}
540
541function wp_ajax_delete_page( $action ) {
542 if ( empty( $action ) )
543 $action = 'delete-page';
544 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
545
546 check_ajax_referer( "{$action}_$id" );
547 if ( !current_user_can( 'delete_page', $id ) )
548 wp_die( -1 );
549
550 if ( ! get_post( $id ) )
551 wp_die( 1 );
552
553 if ( wp_delete_post( $id ) )
554 wp_die( 1 );
555 else
556 wp_die( 0 );
557}
558
559function wp_ajax_dim_comment() {
560 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
561
562 if ( !$comment = get_comment( $id ) ) {
563 $x = new WP_Ajax_Response( array(
564 'what' => 'comment',
565 'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
566 ) );
567 $x->send();
568 }
569
570 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) )
571 wp_die( -1 );
572
573 $current = wp_get_comment_status( $comment->comment_ID );
574 if ( isset( $_POST['new'] ) && $_POST['new'] == $current )
575 wp_die( time() );
576
577 check_ajax_referer( "approve-comment_$id" );
578 if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
579 $result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
580 else
581 $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
582
583 if ( is_wp_error($result) ) {
584 $x = new WP_Ajax_Response( array(
585 'what' => 'comment',
586 'id' => $result
587 ) );
588 $x->send();
589 }
590
591 // Decide if we need to send back '1' or a more complicated response including page links and comment counts
592 _wp_ajax_delete_comment_response( $comment->comment_ID );
593 wp_die( 0 );
594}
595
596function wp_ajax_add_link_category( $action ) {
597 if ( empty( $action ) )
598 $action = 'add-link-category';
599 check_ajax_referer( $action );
600 if ( !current_user_can( 'manage_categories' ) )
601 wp_die( -1 );
602 $names = explode(',', wp_unslash( $_POST['newcat'] ) );
603 $x = new WP_Ajax_Response();
604 foreach ( $names as $cat_name ) {
605 $cat_name = trim($cat_name);
606 $slug = sanitize_title($cat_name);
607 if ( '' === $slug )
608 continue;
609 if ( !$cat_id = term_exists( $cat_name, 'link_category' ) )
610 $cat_id = wp_insert_term( $cat_name, 'link_category' );
611 if ( is_wp_error( $cat_id ) )
612 continue;
613 else if ( is_array( $cat_id ) )
614 $cat_id = $cat_id['term_id'];
615 $cat_name = esc_html( $cat_name );
616 $x->add( array(
617 'what' => 'link-category',
618 'id' => $cat_id,
619 'data' => "<li id='link-category-$cat_id'><label for='in-link-category-$cat_id' class='selectit'><input value='" . esc_attr($cat_id) . "' type='checkbox' checked='checked' name='link_category[]' id='in-link-category-$cat_id'/> $cat_name</label></li>",
620 'position' => -1
621 ) );
622 }
623 $x->send();
624}
625
626function wp_ajax_add_tag() {
627 global $wp_list_table;
628
629 check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
630 $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
631 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
632 $tax = get_taxonomy($taxonomy);
633
634 if ( !current_user_can( $tax->cap->edit_terms ) )
635 wp_die( -1 );
636
637 $x = new WP_Ajax_Response();
638
639 $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
640
641 if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) {
642 $message = __('An error has occurred. Please reload the page and try again.');
643 if ( is_wp_error($tag) && $tag->get_error_message() )
644 $message = $tag->get_error_message();
645
646 $x->add( array(
647 'what' => 'taxonomy',
648 'data' => new WP_Error('error', $message )
649 ) );
650 $x->send();
651 }
652
653 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
654
655 $level = 0;
656 if ( is_taxonomy_hierarchical($taxonomy) ) {
657 $level = count( get_ancestors( $tag->term_id, $taxonomy ) );
658 ob_start();
659 $wp_list_table->single_row( $tag, $level );
660 $noparents = ob_get_clean();
661 }
662
663 ob_start();
664 $wp_list_table->single_row( $tag );
665 $parents = ob_get_clean();
666
667 $x->add( array(
668 'what' => 'taxonomy',
669 'supplemental' => compact('parents', 'noparents')
670 ) );
671 $x->add( array(
672 'what' => 'term',
673 'position' => $level,
674 'supplemental' => (array) $tag
675 ) );
676 $x->send();
677}
678
679function wp_ajax_get_tagcloud() {
680 if ( isset( $_POST['tax'] ) ) {
681 $taxonomy = sanitize_key( $_POST['tax'] );
682 $tax = get_taxonomy( $taxonomy );
683 if ( ! $tax )
684 wp_die( 0 );
685 if ( ! current_user_can( $tax->cap->assign_terms ) )
686 wp_die( -1 );
687 } else {
688 wp_die( 0 );
689 }
690
691 $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
692
693 if ( empty( $tags ) )
694 wp_die( $tax->labels->not_found );
695
696 if ( is_wp_error( $tags ) )
697 wp_die( $tags->get_error_message() );
698
699 foreach ( $tags as $key => $tag ) {
700 $tags[ $key ]->link = '#';
701 $tags[ $key ]->id = $tag->term_id;
702 }
703
704 // We need raw tag names here, so don't filter the output
705 $return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
706
707 if ( empty($return) )
708 wp_die( 0 );
709
710 echo $return;
711
712 wp_die();
713}
714
715function wp_ajax_get_comments( $action ) {
716 global $wp_list_table, $post_id;
717 if ( empty( $action ) )
718 $action = 'get-comments';
719
720 check_ajax_referer( $action );
721
722 if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) {
723 $id = absint( $_REQUEST['p'] );
724 if ( ! empty( $id ) )
725 $post_id = $id;
726 }
727
728 if ( empty( $post_id ) )
729 wp_die( -1 );
730
731 $wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
732
733 if ( ! current_user_can( 'edit_post', $post_id ) )
734 wp_die( -1 );
735
736 $wp_list_table->prepare_items();
737
738 if ( !$wp_list_table->has_items() )
739 wp_die( 1 );
740
741 $x = new WP_Ajax_Response();
742 ob_start();
743 foreach ( $wp_list_table->items as $comment ) {
744 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
745 continue;
746 get_comment( $comment );
747 $wp_list_table->single_row( $comment );
748 }
749 $comment_list_item = ob_get_contents();
750 ob_end_clean();
751
752 $x->add( array(
753 'what' => 'comments',
754 'data' => $comment_list_item
755 ) );
756 $x->send();
757}
758
759function wp_ajax_replyto_comment( $action ) {
760 global $wp_list_table, $wpdb;
761 if ( empty( $action ) )
762 $action = 'replyto-comment';
763
764 check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
765
766 $comment_post_ID = (int) $_POST['comment_post_ID'];
767 $post = get_post( $comment_post_ID );
768 if ( ! $post )
769 wp_die( -1 );
770
771 if ( !current_user_can( 'edit_post', $comment_post_ID ) )
772 wp_die( -1 );
773
774 if ( empty( $post->post_status ) )
775 wp_die( 1 );
776 elseif ( in_array($post->post_status, array('draft', 'pending', 'trash') ) )
777 wp_die( __('ERROR: you are replying to a comment on a draft post.') );
778
779 $user = wp_get_current_user();
780 if ( $user->exists() ) {
781 $user_ID = $user->ID;
782 $comment_author = wp_slash( $user->display_name );
783 $comment_author_email = wp_slash( $user->user_email );
784 $comment_author_url = wp_slash( $user->user_url );
785 $comment_content = trim($_POST['content']);
786 if ( current_user_can( 'unfiltered_html' ) ) {
787 if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) )
788 $_POST['_wp_unfiltered_html_comment'] = '';
789
790 if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
791 kses_remove_filters(); // start with a clean slate
792 kses_init_filters(); // set up the filters
793 }
794 }
795 } else {
796 wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
797 }
798
799 if ( '' == $comment_content )
800 wp_die( __( 'ERROR: please type a comment.' ) );
801
802 $comment_parent = 0;
803 if ( isset( $_POST['comment_ID'] ) )
804 $comment_parent = absint( $_POST['comment_ID'] );
805 $comment_auto_approved = false;
806 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
807
808 // automatically approve parent comment
809 if ( !empty($_POST['approve_parent']) ) {
810 $parent = get_comment( $comment_parent );
811
812 if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
813 if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
814 $comment_auto_approved = true;
815 }
816 }
817
818 $comment_id = wp_new_comment( $commentdata );
819 $comment = get_comment($comment_id);
820 if ( ! $comment ) wp_die( 1 );
821
822 $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
823
824 ob_start();
825 if ( isset( $_REQUEST['mode'] ) && 'dashboard' == $_REQUEST['mode'] ) {
826 require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
827 _wp_dashboard_recent_comments_row( $comment );
828 } else {
829 if ( isset( $_REQUEST['mode'] ) && 'single' == $_REQUEST['mode'] ) {
830 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
831 } else {
832 $wp_list_table = _get_list_table('WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
833 }
834 $wp_list_table->single_row( $comment );
835 }
836 $comment_list_item = ob_get_clean();
837
838 $response = array(
839 'what' => 'comment',
840 'id' => $comment->comment_ID,
841 'data' => $comment_list_item,
842 'position' => $position
843 );
844
845 if ( $comment_auto_approved )
846 $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
847
848 $x = new WP_Ajax_Response();
849 $x->add( $response );
850 $x->send();
851}
852
853function wp_ajax_edit_comment() {
854 global $wp_list_table;
855
856 check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
857
858 $comment_id = (int) $_POST['comment_ID'];
859 if ( ! current_user_can( 'edit_comment', $comment_id ) )
860 wp_die( -1 );
861
862 if ( '' == $_POST['content'] )
863 wp_die( __( 'ERROR: please type a comment.' ) );
864
865 if ( isset( $_POST['status'] ) )
866 $_POST['comment_status'] = $_POST['status'];
867 edit_comment();
868
869 $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
870 $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
871
872 $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
873 $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
874
875 $comment = get_comment( $comment_id );
876 if ( empty( $comment->comment_ID ) )
877 wp_die( -1 );
878
879 ob_start();
880 $wp_list_table->single_row( $comment );
881 $comment_list_item = ob_get_clean();
882
883 $x = new WP_Ajax_Response();
884
885 $x->add( array(
886 'what' => 'edit_comment',
887 'id' => $comment->comment_ID,
888 'data' => $comment_list_item,
889 'position' => $position
890 ));
891
892 $x->send();
893}
894
895function wp_ajax_add_menu_item() {
896 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
897
898 if ( ! current_user_can( 'edit_theme_options' ) )
899 wp_die( -1 );
900
901 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
902
903 // For performance reasons, we omit some object properties from the checklist.
904 // The following is a hacky way to restore them when adding non-custom items.
905
906 $menu_items_data = array();
907 foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
908 if (
909 ! empty( $menu_item_data['menu-item-type'] ) &&
910 'custom' != $menu_item_data['menu-item-type'] &&
911 ! empty( $menu_item_data['menu-item-object-id'] )
912 ) {
913 switch( $menu_item_data['menu-item-type'] ) {
914 case 'post_type' :
915 $_object = get_post( $menu_item_data['menu-item-object-id'] );
916 break;
917
918 case 'taxonomy' :
919 $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
920 break;
921 }
922
923 $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
924 $_menu_item = array_shift( $_menu_items );
925
926 // Restore the missing menu item properties
927 $menu_item_data['menu-item-description'] = $_menu_item->description;
928 }
929
930 $menu_items_data[] = $menu_item_data;
931 }
932
933 $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
934 if ( is_wp_error( $item_ids ) )
935 wp_die( 0 );
936
937 $menu_items = array();
938
939 foreach ( (array) $item_ids as $menu_item_id ) {
940 $menu_obj = get_post( $menu_item_id );
941 if ( ! empty( $menu_obj->ID ) ) {
942 $menu_obj = wp_setup_nav_menu_item( $menu_obj );
943 $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
944 $menu_items[] = $menu_obj;
945 }
946 }
947
948 /**
949 * Filter the Walker class used when adding nav menu items.
950 *
951 * @since 3.4.0
952 *
953 * @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'.
954 * @param int $menu_id The menu id, derived from $_POST['menu'].
955 */
956 $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST['menu'] );
957
958 if ( ! class_exists( $walker_class_name ) )
959 wp_die( 0 );
960
961 if ( ! empty( $menu_items ) ) {
962 $args = array(
963 'after' => '',
964 'before' => '',
965 'link_after' => '',
966 'link_before' => '',
967 'walker' => new $walker_class_name,
968 );
969 echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
970 }
971 wp_die();
972}
973
974function wp_ajax_add_meta() {
975 check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
976 $c = 0;
977 $pid = (int) $_POST['post_id'];
978 $post = get_post( $pid );
979
980 if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
981 if ( !current_user_can( 'edit_post', $pid ) )
982 wp_die( -1 );
983 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
984 wp_die( 1 );
985 if ( $post->post_status == 'auto-draft' ) {
986 $save_POST = $_POST; // Backup $_POST
987 $_POST = array(); // Make it empty for edit_post()
988 $_POST['action'] = 'draft'; // Warning fix
989 $_POST['post_ID'] = $pid;
990 $_POST['post_type'] = $post->post_type;
991 $_POST['post_status'] = 'draft';
992 $now = current_time('timestamp', 1);
993 $_POST['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( get_option( 'date_format' ), $now ), date( get_option( 'time_format' ), $now ) );
994
995 if ( $pid = edit_post() ) {
996 if ( is_wp_error( $pid ) ) {
997 $x = new WP_Ajax_Response( array(
998 'what' => 'meta',
999 'data' => $pid
1000 ) );
1001 $x->send();
1002 }
1003 $_POST = $save_POST; // Now we can restore original $_POST again
1004 if ( !$mid = add_meta( $pid ) )
1005 wp_die( __( 'Please provide a custom field value.' ) );
1006 } else {
1007 wp_die( 0 );
1008 }
1009 } else if ( !$mid = add_meta( $pid ) ) {
1010 wp_die( __( 'Please provide a custom field value.' ) );
1011 }
1012
1013 $meta = get_metadata_by_mid( 'post', $mid );
1014 $pid = (int) $meta->post_id;
1015 $meta = get_object_vars( $meta );
1016 $x = new WP_Ajax_Response( array(
1017 'what' => 'meta',
1018 'id' => $mid,
1019 'data' => _list_meta_row( $meta, $c ),
1020 'position' => 1,
1021 'supplemental' => array('postid' => $pid)
1022 ) );
1023 } else { // Update?
1024 $mid = (int) key( $_POST['meta'] );
1025 $key = wp_unslash( $_POST['meta'][$mid]['key'] );
1026 $value = wp_unslash( $_POST['meta'][$mid]['value'] );
1027 if ( '' == trim($key) )
1028 wp_die( __( 'Please provide a custom field name.' ) );
1029 if ( '' == trim($value) )
1030 wp_die( __( 'Please provide a custom field value.' ) );
1031 if ( ! $meta = get_metadata_by_mid( 'post', $mid ) )
1032 wp_die( 0 ); // if meta doesn't exist
1033 if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
1034 ! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
1035 ! current_user_can( 'edit_post_meta', $meta->post_id, $key ) )
1036 wp_die( -1 );
1037 if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
1038 if ( !$u = update_metadata_by_mid( 'post', $mid, $value, $key ) )
1039 wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
1040 }
1041
1042 $x = new WP_Ajax_Response( array(
1043 'what' => 'meta',
1044 'id' => $mid, 'old_id' => $mid,
1045 'data' => _list_meta_row( array(
1046 'meta_key' => $key,
1047 'meta_value' => $value,
1048 'meta_id' => $mid
1049 ), $c ),
1050 'position' => 0,
1051 'supplemental' => array('postid' => $meta->post_id)
1052 ) );
1053 }
1054 $x->send();
1055}
1056
1057function wp_ajax_add_user( $action ) {
1058 global $wp_list_table;
1059 if ( empty( $action ) )
1060 $action = 'add-user';
1061
1062 check_ajax_referer( $action );
1063 if ( ! current_user_can('create_users') )
1064 wp_die( -1 );
1065 if ( ! $user_id = edit_user() ) {
1066 wp_die( 0 );
1067 } elseif ( is_wp_error( $user_id ) ) {
1068 $x = new WP_Ajax_Response( array(
1069 'what' => 'user',
1070 'id' => $user_id
1071 ) );
1072 $x->send();
1073 }
1074 $user_object = get_userdata( $user_id );
1075
1076 $wp_list_table = _get_list_table('WP_Users_List_Table');
1077
1078 $role = current( $user_object->roles );
1079
1080 $x = new WP_Ajax_Response( array(
1081 'what' => 'user',
1082 'id' => $user_id,
1083 'data' => $wp_list_table->single_row( $user_object, '', $role ),
1084 'supplemental' => array(
1085 'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
1086 'role' => $role,
1087 )
1088 ) );
1089 $x->send();
1090}
1091
1092function wp_ajax_autosave() {
1093 define( 'DOING_AUTOSAVE', true );
1094
1095 check_ajax_referer( 'autosave', 'autosavenonce' );
1096
1097 if ( ! empty( $_POST['catslist'] ) )
1098 $_POST['post_category'] = explode( ',', $_POST['catslist'] );
1099 if ( $_POST['post_type'] == 'page' || empty( $_POST['post_category'] ) )
1100 unset( $_POST['post_category'] );
1101
1102 $data = '';
1103 $supplemental = array();
1104 $id = $revision_id = 0;
1105
1106 $post_id = (int) $_POST['post_id'];
1107 $_POST['ID'] = $_POST['post_ID'] = $post_id;
1108 $post = get_post( $post_id );
1109 if ( empty( $post->ID ) || ! current_user_can( 'edit_post', $post->ID ) )
1110 wp_die( __( 'You are not allowed to edit this post.' ) );
1111
1112 if ( 'page' == $post->post_type && ! current_user_can( 'edit_page', $post->ID ) )
1113 wp_die( __( 'You are not allowed to edit this page.' ) );
1114
1115 if ( 'auto-draft' == $post->post_status )
1116 $_POST['post_status'] = 'draft';
1117
1118 if ( ! empty( $_POST['autosave'] ) ) {
1119 if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
1120 // Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
1121 $id = edit_post();
1122 } else {
1123 // Non drafts or other users drafts are not overwritten. The autosave is stored in a special post revision for each user.
1124 $revision_id = wp_create_post_autosave( $post->ID );
1125 if ( is_wp_error($revision_id) )
1126 $id = $revision_id;
1127 else
1128 $id = $post->ID;
1129 }
1130
1131 if ( ! is_wp_error($id) ) {
1132 /* translators: draft saved date format, see http://php.net/date */
1133 $draft_saved_date_format = __('g:i:s a');
1134 /* translators: %s: date and time */
1135 $data = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
1136 }
1137 } else {
1138 if ( ! empty( $_POST['auto_draft'] ) )
1139 $id = 0; // This tells us it didn't actually save
1140 else
1141 $id = $post->ID;
1142 }
1143
1144 // @todo Consider exposing any errors, rather than having 'Saving draft...'
1145 $x = new WP_Ajax_Response( array(
1146 'what' => 'autosave',
1147 'id' => $id,
1148 'data' => $data,
1149 'supplemental' => $supplemental
1150 ) );
1151 $x->send();
1152}
1153
1154function wp_ajax_closed_postboxes() {
1155 check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1156 $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1157 $closed = array_filter($closed);
1158
1159 $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1160 $hidden = array_filter($hidden);
1161
1162 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1163
1164 if ( $page != sanitize_key( $page ) )
1165 wp_die( 0 );
1166
1167 if ( ! $user = wp_get_current_user() )
1168 wp_die( -1 );
1169
1170 if ( is_array($closed) )
1171 update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1172
1173 if ( is_array($hidden) ) {
1174 $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1175 update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1176 }
1177
1178 wp_die( 1 );
1179}
1180
1181function wp_ajax_hidden_columns() {
1182 check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1183 $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1184 $hidden = explode( ',', $_POST['hidden'] );
1185 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1186
1187 if ( $page != sanitize_key( $page ) )
1188 wp_die( 0 );
1189
1190 if ( ! $user = wp_get_current_user() )
1191 wp_die( -1 );
1192
1193 if ( is_array($hidden) )
1194 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1195
1196 wp_die( 1 );
1197}
1198
1199function wp_ajax_update_welcome_panel() {
1200 check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
1201
1202 if ( ! current_user_can( 'edit_theme_options' ) )
1203 wp_die( -1 );
1204
1205 update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 );
1206
1207 wp_die( 1 );
1208}
1209
1210function wp_ajax_menu_get_metabox() {
1211 if ( ! current_user_can( 'edit_theme_options' ) )
1212 wp_die( -1 );
1213
1214 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1215
1216 if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1217 $type = 'posttype';
1218 $callback = 'wp_nav_menu_item_post_type_meta_box';
1219 $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1220 } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1221 $type = 'taxonomy';
1222 $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1223 $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1224 }
1225
1226 if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1227 $menus_meta_box_object = $items[ $_POST['item-object'] ];
1228 /**
1229 * Filter a nav menu meta box object.
1230 *
1231 * @since 3.0.0
1232 *
1233 * @param object $menus_meta_box_object A nav menu meta box object, such as Page, Post, Category, Tag, etc.
1234 */
1235 $item = apply_filters( 'nav_menu_meta_box_object', $menus_meta_box_object );
1236 ob_start();
1237 call_user_func_array($callback, array(
1238 null,
1239 array(
1240 'id' => 'add-' . $item->name,
1241 'title' => $item->labels->name,
1242 'callback' => $callback,
1243 'args' => $item,
1244 )
1245 ));
1246
1247 $markup = ob_get_clean();
1248
1249 echo json_encode(array(
1250 'replace-id' => $type . '-' . $item->name,
1251 'markup' => $markup,
1252 ));
1253 }
1254
1255 wp_die();
1256}
1257
1258function wp_ajax_wp_link_ajax() {
1259 check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1260
1261 $args = array();
1262
1263 if ( isset( $_POST['search'] ) )
1264 $args['s'] = wp_unslash( $_POST['search'] );
1265 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1266
1267 require(ABSPATH . WPINC . '/class-wp-editor.php');
1268 $results = _WP_Editors::wp_link_query( $args );
1269
1270 if ( ! isset( $results ) )
1271 wp_die( 0 );
1272
1273 echo json_encode( $results );
1274 echo "\n";
1275
1276 wp_die();
1277}
1278
1279function wp_ajax_menu_locations_save() {
1280 if ( ! current_user_can( 'edit_theme_options' ) )
1281 wp_die( -1 );
1282 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1283 if ( ! isset( $_POST['menu-locations'] ) )
1284 wp_die( 0 );
1285 set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1286 wp_die( 1 );
1287}
1288
1289function wp_ajax_meta_box_order() {
1290 check_ajax_referer( 'meta-box-order' );
1291 $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1292 $page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
1293
1294 if ( $page_columns != 'auto' )
1295 $page_columns = (int) $page_columns;
1296
1297 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1298
1299 if ( $page != sanitize_key( $page ) )
1300 wp_die( 0 );
1301
1302 if ( ! $user = wp_get_current_user() )
1303 wp_die( -1 );
1304
1305 if ( $order )
1306 update_user_option($user->ID, "meta-box-order_$page", $order, true);
1307
1308 if ( $page_columns )
1309 update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1310
1311 wp_die( 1 );
1312}
1313
1314function wp_ajax_menu_quick_search() {
1315 if ( ! current_user_can( 'edit_theme_options' ) )
1316 wp_die( -1 );
1317
1318 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1319
1320 _wp_ajax_menu_quick_search( $_POST );
1321
1322 wp_die();
1323}
1324
1325function wp_ajax_get_permalink() {
1326 check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1327 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1328 wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) );
1329}
1330
1331function wp_ajax_sample_permalink() {
1332 check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1333 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1334 $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1335 $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1336 wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
1337}
1338
1339function wp_ajax_inline_save() {
1340 global $wp_list_table;
1341
1342 check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1343
1344 if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1345 wp_die();
1346
1347 if ( 'page' == $_POST['post_type'] ) {
1348 if ( ! current_user_can( 'edit_page', $post_ID ) )
1349 wp_die( __( 'You are not allowed to edit this page.' ) );
1350 } else {
1351 if ( ! current_user_can( 'edit_post', $post_ID ) )
1352 wp_die( __( 'You are not allowed to edit this post.' ) );
1353 }
1354
1355 if ( $last = wp_check_post_lock( $post_ID ) ) {
1356 $last_user = get_userdata( $last );
1357 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1358 printf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ), esc_html( $last_user_name ) );
1359 wp_die();
1360 }
1361
1362 $data = &$_POST;
1363
1364 $post = get_post( $post_ID, ARRAY_A );
1365 $post = wp_slash($post); //since it is from db
1366
1367 $data['content'] = $post['post_content'];
1368 $data['excerpt'] = $post['post_excerpt'];
1369
1370 // rename
1371 $data['user_ID'] = get_current_user_id();
1372
1373 if ( isset($data['post_parent']) )
1374 $data['parent_id'] = $data['post_parent'];
1375
1376 // status
1377 if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1378 $data['post_status'] = 'private';
1379 else
1380 $data['post_status'] = $data['_status'];
1381
1382 if ( empty($data['comment_status']) )
1383 $data['comment_status'] = 'closed';
1384 if ( empty($data['ping_status']) )
1385 $data['ping_status'] = 'closed';
1386
1387 // Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
1388 if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
1389 $post['post_status'] = 'publish';
1390 $data['post_name'] = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
1391 }
1392
1393 // update the post
1394 edit_post();
1395
1396 $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
1397
1398 $mode = $_POST['post_view'];
1399
1400 $level = 0;
1401 $request_post = array( get_post( $_POST['post_ID'] ) );
1402 $parent = $request_post[0]->post_parent;
1403
1404 while ( $parent > 0 ) {
1405 $parent_post = get_post( $parent );
1406 $parent = $parent_post->post_parent;
1407 $level++;
1408 }
1409
1410 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
1411
1412 wp_die();
1413}
1414
1415function wp_ajax_inline_save_tax() {
1416 global $wp_list_table;
1417
1418 check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1419
1420 $taxonomy = sanitize_key( $_POST['taxonomy'] );
1421 $tax = get_taxonomy( $taxonomy );
1422 if ( ! $tax )
1423 wp_die( 0 );
1424
1425 if ( ! current_user_can( $tax->cap->edit_terms ) )
1426 wp_die( -1 );
1427
1428 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
1429
1430 if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1431 wp_die( -1 );
1432
1433 $tag = get_term( $id, $taxonomy );
1434 $_POST['description'] = $tag->description;
1435
1436 $updated = wp_update_term($id, $taxonomy, $_POST);
1437 if ( $updated && !is_wp_error($updated) ) {
1438 $tag = get_term( $updated['term_id'], $taxonomy );
1439 if ( !$tag || is_wp_error( $tag ) ) {
1440 if ( is_wp_error($tag) && $tag->get_error_message() )
1441 wp_die( $tag->get_error_message() );
1442 wp_die( __( 'Item not updated.' ) );
1443 }
1444 } else {
1445 if ( is_wp_error($updated) && $updated->get_error_message() )
1446 wp_die( $updated->get_error_message() );
1447 wp_die( __( 'Item not updated.' ) );
1448 }
1449 $level = 0;
1450 $parent = $tag->parent;
1451 while ( $parent > 0 ) {
1452 $parent_tag = get_term( $parent, $taxonomy );
1453 $parent = $parent_tag->parent;
1454 $level++;
1455 }
1456 $wp_list_table->single_row( $tag, $level );
1457 wp_die();
1458}
1459
1460function wp_ajax_find_posts() {
1461 global $wpdb;
1462
1463 check_ajax_referer( 'find-posts' );
1464
1465 $post_types = get_post_types( array( 'public' => true ), 'objects' );
1466 unset( $post_types['attachment'] );
1467
1468 $s = wp_unslash( $_POST['ps'] );
1469 $searchand = $search = '';
1470 $args = array(
1471 'post_type' => array_keys( $post_types ),
1472 'post_status' => 'any',
1473 'posts_per_page' => 50,
1474 );
1475 if ( '' !== $s )
1476 $args['s'] = $s;
1477
1478 $posts = get_posts( $args );
1479
1480 if ( ! $posts )
1481 wp_die( __('No items found.') );
1482
1483 $html = '<table class="widefat" cellspacing="0"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th class="no-break">'.__('Type').'</th><th class="no-break">'.__('Date').'</th><th class="no-break">'.__('Status').'</th></tr></thead><tbody>';
1484 foreach ( $posts as $post ) {
1485 $title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
1486
1487 switch ( $post->post_status ) {
1488 case 'publish' :
1489 case 'private' :
1490 $stat = __('Published');
1491 break;
1492 case 'future' :
1493 $stat = __('Scheduled');
1494 break;
1495 case 'pending' :
1496 $stat = __('Pending Review');
1497 break;
1498 case 'draft' :
1499 $stat = __('Draft');
1500 break;
1501 }
1502
1503 if ( '0000-00-00 00:00:00' == $post->post_date ) {
1504 $time = '';
1505 } else {
1506 /* translators: date format in table columns, see http://php.net/date */
1507 $time = mysql2date(__('Y/m/d'), $post->post_date);
1508 }
1509
1510 $html .= '<tr class="found-posts"><td class="found-radio"><input type="radio" id="found-'.$post->ID.'" name="found_post_id" value="' . esc_attr($post->ID) . '"></td>';
1511 $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";
1512 }
1513
1514 $html .= '</tbody></table>';
1515
1516 $x = new WP_Ajax_Response();
1517 $x->add( array(
1518 'data' => $html
1519 ));
1520 $x->send();
1521}
1522
1523function wp_ajax_widgets_order() {
1524 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1525
1526 if ( !current_user_can('edit_theme_options') )
1527 wp_die( -1 );
1528
1529 unset( $_POST['savewidgets'], $_POST['action'] );
1530
1531 // save widgets order for all sidebars
1532 if ( is_array($_POST['sidebars']) ) {
1533 $sidebars = array();
1534 foreach ( $_POST['sidebars'] as $key => $val ) {
1535 $sb = array();
1536 if ( !empty($val) ) {
1537 $val = explode(',', $val);
1538 foreach ( $val as $k => $v ) {
1539 if ( strpos($v, 'widget-') === false )
1540 continue;
1541
1542 $sb[$k] = substr($v, strpos($v, '_') + 1);
1543 }
1544 }
1545 $sidebars[$key] = $sb;
1546 }
1547 wp_set_sidebars_widgets($sidebars);
1548 wp_die( 1 );
1549 }
1550
1551 wp_die( -1 );
1552}
1553
1554function wp_ajax_save_widget() {
1555 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;
1556
1557 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1558
1559 if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1560 wp_die( -1 );
1561
1562 unset( $_POST['savewidgets'], $_POST['action'] );
1563
1564 /**
1565 * Fires early when editing the widgets displayed in sidebars.
1566 *
1567 * @since 2.8.0
1568 */
1569 do_action( 'load-widgets.php' );
1570
1571 /**
1572 * Fires early when editing the widgets displayed in sidebars.
1573 *
1574 * @since 2.8.0
1575 */
1576 do_action( 'widgets.php' );
1577
1578 /**
1579 * Fires early when editing the widgets displayed in sidebars.
1580 *
1581 * @since 2.2.0
1582 */
1583 do_action( 'sidebar_admin_setup' );
1584
1585 $id_base = $_POST['id_base'];
1586 $widget_id = $_POST['widget-id'];
1587 $sidebar_id = $_POST['sidebar'];
1588 $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1589 $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1590 $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1591
1592 $sidebars = wp_get_sidebars_widgets();
1593 $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1594
1595 // delete
1596 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1597
1598 if ( !isset($wp_registered_widgets[$widget_id]) )
1599 wp_die( $error );
1600
1601 $sidebar = array_diff( $sidebar, array($widget_id) );
1602 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1603 } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1604 if ( !$multi_number )
1605 wp_die( $error );
1606
1607 $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1608 $widget_id = $id_base . '-' . $multi_number;
1609 $sidebar[] = $widget_id;
1610 }
1611 $_POST['widget-id'] = $sidebar;
1612
1613 foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1614
1615 if ( $name == $id_base ) {
1616 if ( !is_callable( $control['callback'] ) )
1617 continue;
1618
1619 ob_start();
1620 call_user_func_array( $control['callback'], $control['params'] );
1621 ob_end_clean();
1622 break;
1623 }
1624 }
1625
1626 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1627 $sidebars[$sidebar_id] = $sidebar;
1628 wp_set_sidebars_widgets($sidebars);
1629 echo "deleted:$widget_id";
1630 wp_die();
1631 }
1632
1633 if ( !empty($_POST['add_new']) )
1634 wp_die();
1635
1636 if ( $form = $wp_registered_widget_controls[$widget_id] )
1637 call_user_func_array( $form['callback'], $form['params'] );
1638
1639 wp_die();
1640}
1641
1642function wp_ajax_upload_attachment() {
1643 check_ajax_referer( 'media-form' );
1644
1645 if ( ! current_user_can( 'upload_files' ) )
1646 wp_die();
1647
1648 if ( isset( $_REQUEST['post_id'] ) ) {
1649 $post_id = $_REQUEST['post_id'];
1650 if