3 * WordPress AJAX Process Execution.
6 * @subpackage Administration
10 * Executing AJAX process.
14 define('DOING_AJAX', true);
15 define('WP_ADMIN', true);
17 if ( ! isset( $_REQUEST['action'] ) )
20 require_once('../wp-load.php');
22 require_once('./includes/admin.php');
23 @header('Content-Type: text/html; charset=' . get_option('blog_charset'));
24 send_nosniff_header();
26 do_action('admin_init');
28 if ( ! is_user_logged_in() ) {
30 if ( isset( $_POST['action'] ) && $_POST['action'] == 'autosave' ) {
31 $id = isset($_POST['post_ID'])? (int) $_POST['post_ID'] : 0;
36 $message = sprintf( __('<strong>ALERT: You are logged out!</strong> Could not save draft. <a href="%s" target="_blank">Please log in again.</a>'), wp_login_url() );
37 $x = new WP_Ajax_Response( array(
45 if ( !empty( $_REQUEST['action'] ) )
46 do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
51 if ( isset( $_GET['action'] ) ) :
52 switch ( $action = $_GET['action'] ) :
55 $list_class = $_GET['list_args']['class'];
56 check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' );
58 $current_screen = (object) $_GET['list_args']['screen'];
59 //TODO fix this in a better way see #15336
60 $current_screen->is_network = 'false' === $current_screen->is_network ? false : true;
61 $current_screen->is_user = 'false' === $current_screen->is_user ? false : true;
63 define( 'WP_NETWORK_ADMIN', $current_screen->is_network );
64 define( 'WP_USER_ADMIN', $current_screen->is_user );
66 $wp_list_table = _get_list_table( $list_class );
67 if ( ! $wp_list_table )
70 if ( ! $wp_list_table->ajax_user_can() )
73 $wp_list_table->ajax_response();
77 case 'ajax-tag-search' :
78 if ( isset( $_GET['tax'] ) ) {
79 $taxonomy = sanitize_key( $_GET['tax'] );
80 $tax = get_taxonomy( $taxonomy );
83 if ( ! current_user_can( $tax->cap->assign_terms ) )
89 $s = stripslashes( $_GET['q'] );
91 if ( false !== strpos( $s, ',' ) ) {
92 $s = explode( ',', $s );
93 $s = $s[count( $s ) - 1];
96 if ( strlen( $s ) < 2 )
97 die; // require 2 chars for matching
99 $results = $wpdb->get_col( $wpdb->prepare( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.name LIKE (%s)", $taxonomy, '%' . like_escape( $s ) . '%' ) );
101 echo join( $results, "\n" );
104 case 'wp-compression-test' :
105 if ( !current_user_can( 'manage_options' ) )
108 if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) {
109 update_site_option('can_compress_scripts', 0);
113 if ( isset($_GET['test']) ) {
114 header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
115 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
116 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
117 header( 'Pragma: no-cache' );
118 header('Content-Type: application/x-javascript; charset=UTF-8');
119 $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP );
120 $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."';
122 if ( 1 == $_GET['test'] ) {
125 } elseif ( 2 == $_GET['test'] ) {
126 if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
128 if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && ! $force_gzip ) {
129 header('Content-Encoding: deflate');
130 $out = gzdeflate( $test_str, 1 );
131 } elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) {
132 header('Content-Encoding: gzip');
133 $out = gzencode( $test_str, 1 );
139 } elseif ( 'no' == $_GET['test'] ) {
140 update_site_option('can_compress_scripts', 0);
141 } elseif ( 'yes' == $_GET['test'] ) {
142 update_site_option('can_compress_scripts', 1);
148 case 'imgedit-preview' :
149 $post_id = intval($_GET['postid']);
150 if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
153 check_ajax_referer( "image_editor-$post_id" );
155 include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
156 if ( ! stream_preview_image($post_id) )
161 case 'menu-quick-search':
162 if ( ! current_user_can( 'edit_theme_options' ) )
165 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
167 _wp_ajax_menu_quick_search( $_REQUEST );
171 case 'oembed-cache' :
172 $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
176 do_action( 'wp_ajax_' . $_GET['action'] );
183 * Sends back current comment total and new page links if they need to be updated.
185 * Contrary to normal success AJAX response ("1"), die with time() on success.
189 * @param int $comment_id
192 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
193 $total = (int) @$_POST['_total'];
194 $per_page = (int) @$_POST['_per_page'];
195 $page = (int) @$_POST['_page'];
196 $url = esc_url_raw( @$_POST['_url'] );
197 // JS didn't send us everything we need to know. Just die with success message
198 if ( !$total || !$per_page || !$page || !$url )
199 die( (string) time() );
205 // Only do the expensive stuff on a page-break, and about 1 other time per page
206 if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
208 $status = 'total_comments'; // What type of comment count are we looking for?
209 $parsed = parse_url( $url );
210 if ( isset( $parsed['query'] ) ) {
211 parse_str( $parsed['query'], $query_vars );
212 if ( !empty( $query_vars['comment_status'] ) )
213 $status = $query_vars['comment_status'];
214 if ( !empty( $query_vars['p'] ) )
215 $post_id = (int) $query_vars['p'];
218 $comment_count = wp_count_comments($post_id);
220 if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count
221 $total = $comment_count->$status;
222 // else use the decremented value from above
225 $time = time(); // The time since the last comment count
227 $x = new WP_Ajax_Response( array(
229 'id' => $comment_id, // here for completeness - not used
230 'supplemental' => array(
231 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
232 'total_pages' => ceil( $total / $per_page ),
233 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
241 function _wp_ajax_add_hierarchical_term() {
242 $action = $_POST['action'];
243 $taxonomy = get_taxonomy(substr($action, 4));
244 check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
245 if ( !current_user_can( $taxonomy->cap->edit_terms ) )
247 $names = explode(',', $_POST['new'.$taxonomy->name]);
248 $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
251 if ( $taxonomy->name == 'category' )
252 $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
254 $post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array();
255 $checked_categories = array_map( 'absint', (array) $post_category );
256 $popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false);
258 foreach ( $names as $cat_name ) {
259 $cat_name = trim($cat_name);
260 $category_nicename = sanitize_title($cat_name);
261 if ( '' === $category_nicename )
263 if ( !($cat_id = term_exists($cat_name, $taxonomy->name, $parent)) ) {
264 $new_term = wp_insert_term($cat_name, $taxonomy->name, array('parent' => $parent));
265 $cat_id = $new_term['term_id'];
267 $checked_categories[] = $cat_id;
268 if ( $parent ) // Do these all at once in a second
270 $category = get_term( $cat_id, $taxonomy->name );
272 wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids ));
273 $data = ob_get_contents();
276 'what' => $taxonomy->name,
278 'data' => str_replace( array("\n", "\t"), '', $data),
283 if ( $parent ) { // Foncy - replace the parent and all its children
284 $parent = get_term( $parent, $taxonomy->name );
285 $term_id = $parent->term_id;
287 while ( $parent->parent ) { // get the top parent
288 $parent = &get_term( $parent->parent, $taxonomy->name );
289 if ( is_wp_error( $parent ) )
291 $term_id = $parent->term_id;
295 wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids));
296 $data = ob_get_contents();
299 'what' => $taxonomy->name,
301 'data' => str_replace( array("\n", "\t"), '', $data),
307 wp_dropdown_categories( array(
308 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name',
309 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —'
311 $sup = ob_get_contents();
313 $add['supplemental'] = array( 'newcat_parent' => $sup );
315 $x = new WP_Ajax_Response( $add );
319 $id = isset($_POST['id'])? (int) $_POST['id'] : 0;
320 switch ( $action = $_POST['action'] ) :
321 case 'delete-comment' : // On success, die with time() instead of 1
322 if ( !$comment = get_comment( $id ) )
323 die( (string) time() );
324 if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
327 check_ajax_referer( "delete-comment_$id" );
328 $status = wp_get_comment_status( $comment->comment_ID );
331 if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
332 if ( 'trash' == $status )
333 die( (string) time() );
334 $r = wp_trash_comment( $comment->comment_ID );
335 } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
336 if ( 'trash' != $status )
337 die( (string) time() );
338 $r = wp_untrash_comment( $comment->comment_ID );
339 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
341 } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
342 if ( 'spam' == $status )
343 die( (string) time() );
344 $r = wp_spam_comment( $comment->comment_ID );
345 } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
346 if ( 'spam' != $status )
347 die( (string) time() );
348 $r = wp_unspam_comment( $comment->comment_ID );
349 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
351 } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
352 $r = wp_delete_comment( $comment->comment_ID );
357 if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts
358 _wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
362 $tag_id = (int) $_POST['tag_ID'];
363 check_ajax_referer( "delete-tag_$tag_id" );
365 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
366 $tax = get_taxonomy($taxonomy);
368 if ( !current_user_can( $tax->cap->delete_terms ) )
371 $tag = get_term( $tag_id, $taxonomy );
372 if ( !$tag || is_wp_error( $tag ) )
375 if ( wp_delete_term($tag_id, $taxonomy))
381 check_ajax_referer( "delete-bookmark_$id" );
382 if ( !current_user_can( 'manage_links' ) )
385 $link = get_bookmark( $id );
386 if ( !$link || is_wp_error( $link ) )
389 if ( wp_delete_link( $id ) )
395 check_ajax_referer( "delete-meta_$id" );
396 if ( !$meta = get_post_meta_by_id( $id ) )
399 if ( !current_user_can( 'edit_post', $meta->post_id ) )
401 if ( delete_meta( $meta->meta_id ) )
406 check_ajax_referer( "{$action}_$id" );
407 if ( !current_user_can( 'delete_post', $id ) )
410 if ( !get_post( $id ) )
413 if ( wp_delete_post( $id ) )
419 case 'untrash-post' :
420 check_ajax_referer( "{$action}_$id" );
421 if ( !current_user_can( 'delete_post', $id ) )
424 if ( !get_post( $id ) )
427 if ( 'trash-post' == $action )
428 $done = wp_trash_post( $id );
430 $done = wp_untrash_post( $id );
438 check_ajax_referer( "{$action}_$id" );
439 if ( !current_user_can( 'delete_page', $id ) )
442 if ( !get_page( $id ) )
445 if ( wp_delete_post( $id ) )
450 case 'dim-comment' : // On success, die with time() instead of 1
452 if ( !$comment = get_comment( $id ) ) {
453 $x = new WP_Ajax_Response( array(
455 'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
460 if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
463 $current = wp_get_comment_status( $comment->comment_ID );
464 if ( $_POST['new'] == $current )
465 die( (string) time() );
467 check_ajax_referer( "approve-comment_$id" );
468 if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
469 $result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
471 $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
473 if ( is_wp_error($result) ) {
474 $x = new WP_Ajax_Response( array(
481 // Decide if we need to send back '1' or a more complicated response including page links and comment counts
482 _wp_ajax_delete_comment_response( $comment->comment_ID );
485 case 'add-link-category' : // On the Fly
486 check_ajax_referer( $action );
487 if ( !current_user_can( 'manage_categories' ) )
489 $names = explode(',', $_POST['newcat']);
490 $x = new WP_Ajax_Response();
491 foreach ( $names as $cat_name ) {
492 $cat_name = trim($cat_name);
493 $slug = sanitize_title($cat_name);
496 if ( !$cat_id = term_exists( $cat_name, 'link_category' ) ) {
497 $cat_id = wp_insert_term( $cat_name, 'link_category' );
499 $cat_id = $cat_id['term_id'];
500 $cat_name = esc_html(stripslashes($cat_name));
502 'what' => 'link-category',
504 '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>",
511 check_ajax_referer( 'add-tag' );
512 $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
513 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
514 $tax = get_taxonomy($taxonomy);
516 if ( !current_user_can( $tax->cap->edit_terms ) )
519 $x = new WP_Ajax_Response();
521 $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
523 if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) {
524 $message = __('An error has occurred. Please reload the page and try again.');
525 if ( is_wp_error($tag) && $tag->get_error_message() )
526 $message = $tag->get_error_message();
529 'what' => 'taxonomy',
530 'data' => new WP_Error('error', $message )
535 set_current_screen( $_POST['screen'] );
537 $wp_list_table = _get_list_table('WP_Terms_List_Table');
540 if ( is_taxonomy_hierarchical($taxonomy) ) {
541 $level = count( get_ancestors( $tag->term_id, $taxonomy ) );
543 $wp_list_table->single_row( $tag, $level );
544 $noparents = ob_get_clean();
548 $wp_list_table->single_row( $tag );
549 $parents = ob_get_clean();
552 'what' => 'taxonomy',
553 'supplemental' => compact('parents', 'noparents')
557 'position' => $level,
558 'supplemental' => (array) $tag
562 case 'get-tagcloud' :
563 if ( isset( $_POST['tax'] ) ) {
564 $taxonomy = sanitize_key( $_POST['tax'] );
565 $tax = get_taxonomy( $taxonomy );
568 if ( ! current_user_can( $tax->cap->assign_terms ) )
574 $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
576 if ( empty( $tags ) )
577 die( isset( $tax->no_tagcloud ) ? $tax->no_tagcloud : __('No tags found!') );
579 if ( is_wp_error( $tags ) )
580 die( $tags->get_error_message() );
582 foreach ( $tags as $key => $tag ) {
583 $tags[ $key ]->link = '#';
584 $tags[ $key ]->id = $tag->term_id;
587 // We need raw tag names here, so don't filter the output
588 $return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
590 if ( empty($return) )
597 case 'get-comments' :
598 check_ajax_referer( $action );
600 set_current_screen( 'edit-comments' );
602 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
604 if ( !current_user_can( 'edit_post', $post_id ) )
607 $wp_list_table->prepare_items();
609 if ( !$wp_list_table->has_items() )
612 $comment_list_item = '';
613 $x = new WP_Ajax_Response();
614 foreach ( $wp_list_table->items as $comment ) {
615 get_comment( $comment );
617 $wp_list_table->single_row( $comment );
618 $comment_list_item .= ob_get_contents();
622 'what' => 'comments',
623 'data' => $comment_list_item
627 case 'replyto-comment' :
628 check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
630 set_current_screen( 'edit-comments' );
632 $comment_post_ID = (int) $_POST['comment_post_ID'];
633 if ( !current_user_can( 'edit_post', $comment_post_ID ) )
636 $status = $wpdb->get_var( $wpdb->prepare("SELECT post_status FROM $wpdb->posts WHERE ID = %d", $comment_post_ID) );
638 if ( empty($status) )
640 elseif ( in_array($status, array('draft', 'pending', 'trash') ) )
641 die( __('Error: you are replying to a comment on a draft post.') );
643 $user = wp_get_current_user();
645 $comment_author = $wpdb->escape($user->display_name);
646 $comment_author_email = $wpdb->escape($user->user_email);
647 $comment_author_url = $wpdb->escape($user->user_url);
648 $comment_content = trim($_POST['content']);
649 if ( current_user_can('unfiltered_html') ) {
650 if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) {
651 kses_remove_filters(); // start with a clean slate
652 kses_init_filters(); // set up the filters
656 die( __('Sorry, you must be logged in to reply to a comment.') );
659 if ( '' == $comment_content )
660 die( __('Error: please type a comment.') );
662 $comment_parent = absint($_POST['comment_ID']);
663 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
665 $comment_id = wp_new_comment( $commentdata );
666 $comment = get_comment($comment_id);
667 if ( ! $comment ) die('1');
669 $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
671 $x = new WP_Ajax_Response();
674 if ( 'dashboard' == $_REQUEST['mode'] ) {
675 require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
676 _wp_dashboard_recent_comments_row( $comment );
678 if ( 'single' == $_REQUEST['mode'] ) {
679 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
681 $wp_list_table = _get_list_table('WP_Comments_List_Table');
683 $wp_list_table->single_row( $comment );
685 $comment_list_item = ob_get_contents();
690 'id' => $comment->comment_ID,
691 'data' => $comment_list_item,
692 'position' => $position
697 case 'edit-comment' :
698 check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
700 set_current_screen( 'edit-comments' );
702 $comment_post_ID = (int) $_POST['comment_post_ID'];
703 if ( ! current_user_can( 'edit_post', $comment_post_ID ) )
706 if ( '' == $_POST['content'] )
707 die( __('Error: please type a comment.') );
709 $comment_id = (int) $_POST['comment_ID'];
710 $_POST['comment_status'] = $_POST['status'];
713 $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
714 $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
716 $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
717 $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table' );
720 $wp_list_table->single_row( get_comment( $comment_id ) );
721 $comment_list_item = ob_get_contents();
724 $x = new WP_Ajax_Response();
727 'what' => 'edit_comment',
728 'id' => $comment->comment_ID,
729 'data' => $comment_list_item,
730 'position' => $position
735 case 'add-menu-item' :
736 if ( ! current_user_can( 'edit_theme_options' ) )
739 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
741 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
743 // For performance reasons, we omit some object properties from the checklist.
744 // The following is a hacky way to restore them when adding non-custom items.
746 $menu_items_data = array();
747 foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
749 ! empty( $menu_item_data['menu-item-type'] ) &&
750 'custom' != $menu_item_data['menu-item-type'] &&
751 ! empty( $menu_item_data['menu-item-object-id'] )
753 switch( $menu_item_data['menu-item-type'] ) {
755 $_object = get_post( $menu_item_data['menu-item-object-id'] );
759 $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
763 $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
764 $_menu_item = array_shift( $_menu_items );
766 // Restore the missing menu item properties
767 $menu_item_data['menu-item-description'] = $_menu_item->description;
770 $menu_items_data[] = $menu_item_data;
773 $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
774 if ( is_wp_error( $item_ids ) )
777 foreach ( (array) $item_ids as $menu_item_id ) {
778 $menu_obj = get_post( $menu_item_id );
779 if ( ! empty( $menu_obj->ID ) ) {
780 $menu_obj = wp_setup_nav_menu_item( $menu_obj );
781 $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
782 $menu_items[] = $menu_obj;
786 if ( ! empty( $menu_items ) ) {
792 'walker' => new Walker_Nav_Menu_Edit,
794 echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
798 check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
800 $pid = (int) $_POST['post_id'];
801 $post = get_post( $pid );
803 if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
804 if ( !current_user_can( 'edit_post', $pid ) )
806 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
808 if ( $post->post_status == 'auto-draft' ) {
809 $save_POST = $_POST; // Backup $_POST
810 $_POST = array(); // Make it empty for edit_post()
811 $_POST['action'] = 'draft'; // Warning fix
812 $_POST['post_ID'] = $pid;
813 $_POST['post_type'] = $post->post_type;
814 $_POST['post_status'] = 'draft';
815 $now = current_time('timestamp', 1);
816 $_POST['post_title'] = sprintf('Draft created on %s at %s', date(get_option('date_format'), $now), date(get_option('time_format'), $now));
818 if ( $pid = edit_post() ) {
819 if ( is_wp_error( $pid ) ) {
820 $x = new WP_Ajax_Response( array(
826 $_POST = $save_POST; // Now we can restore original $_POST again
827 if ( !$mid = add_meta( $pid ) )
828 die(__('Please provide a custom field value.'));
832 } else if ( !$mid = add_meta( $pid ) ) {
833 die(__('Please provide a custom field value.'));
836 $meta = get_post_meta_by_id( $mid );
837 $pid = (int) $meta->post_id;
838 $meta = get_object_vars( $meta );
839 $x = new WP_Ajax_Response( array(
842 'data' => _list_meta_row( $meta, $c ),
844 'supplemental' => array('postid' => $pid)
847 $mid = (int) array_pop( $var_by_ref = array_keys($_POST['meta']) );
848 $key = $_POST['meta'][$mid]['key'];
849 $value = $_POST['meta'][$mid]['value'];
850 if ( '' == trim($key) )
851 die(__('Please provide a custom field name.'));
852 if ( '' == trim($value) )
853 die(__('Please provide a custom field value.'));
854 if ( !$meta = get_post_meta_by_id( $mid ) )
855 die('0'); // if meta doesn't exist
856 if ( !current_user_can( 'edit_post', $meta->post_id ) )
858 if ( $meta->meta_value != stripslashes($value) || $meta->meta_key != stripslashes($key) ) {
859 if ( !$u = update_meta( $mid, $key, $value ) )
860 die('0'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
863 $key = stripslashes($key);
864 $value = stripslashes($value);
865 $x = new WP_Ajax_Response( array(
867 'id' => $mid, 'old_id' => $mid,
868 'data' => _list_meta_row( array(
870 'meta_value' => $value,
874 'supplemental' => array('postid' => $meta->post_id)
880 check_ajax_referer( $action );
881 if ( !current_user_can('create_users') )
883 if ( !$user_id = add_user() )
885 elseif ( is_wp_error( $user_id ) ) {
886 $x = new WP_Ajax_Response( array(
892 $user_object = new WP_User( $user_id );
894 $wp_list_table = _get_list_table('WP_Users_List_Table');
896 $x = new WP_Ajax_Response( array(
899 'data' => $wp_list_table->single_row( $user_object, '', $user_object->roles[0] ),
900 'supplemental' => array(
901 'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
902 'role' => $user_object->roles[0]
907 case 'autosave' : // The name of this action is hardcoded in edit_post()
908 define( 'DOING_AUTOSAVE', true );
910 $nonce_age = check_ajax_referer( 'autosave', 'autosavenonce' );
912 $_POST['post_category'] = explode(",", $_POST['catslist']);
913 if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
914 unset($_POST['post_category']);
916 $do_autosave = (bool) $_POST['autosave'];
920 /* translators: draft saved date format, see http://php.net/date */
921 $draft_saved_date_format = __('g:i:s a');
922 /* translators: %s: date and time */
923 $message = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
925 $supplemental = array();
926 if ( isset($login_grace_period) )
927 $supplemental['session_expired'] = add_query_arg( 'interim-login', 1, wp_login_url() );
929 $id = $revision_id = 0;
931 $post_ID = (int) $_POST['post_ID'];
932 $_POST['ID'] = $post_ID;
933 $post = get_post($post_ID);
934 if ( 'auto-draft' == $post->post_status )
935 $_POST['post_status'] = 'draft';
937 if ( $last = wp_check_post_lock( $post->ID ) ) {
938 $do_autosave = $do_lock = false;
940 $last_user = get_userdata( $last );
941 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
942 $data = new WP_Error( 'locked', sprintf(
943 $_POST['post_type'] == 'page' ? __( 'Autosave disabled: %s is currently editing this page.' ) : __( 'Autosave disabled: %s is currently editing this post.' ),
944 esc_html( $last_user_name )
947 $supplemental['disable_autosave'] = 'disable';
950 if ( 'page' == $post->post_type ) {
951 if ( !current_user_can('edit_page', $post_ID) )
952 die(__('You are not allowed to edit this page.'));
954 if ( !current_user_can('edit_post', $post_ID) )
955 die(__('You are not allowed to edit this post.'));
958 if ( $do_autosave ) {
959 // Drafts and auto-drafts are just overwritten by autosave
960 if ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) {
962 } else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
963 $revision_id = wp_create_post_autosave( $post->ID );
964 if ( is_wp_error($revision_id) )
971 if ( isset( $_POST['auto_draft'] ) && '1' == $_POST['auto_draft'] )
972 $id = 0; // This tells us it didn't actually save
977 if ( $do_lock && ( isset( $_POST['auto_draft'] ) && ( $_POST['auto_draft'] != '1' ) ) && $id && is_numeric($id) )
978 wp_set_post_lock( $id );
980 if ( $nonce_age == 2 ) {
981 $supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
982 $supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
983 $supplemental['replace-samplepermalinknonce'] = wp_create_nonce('samplepermalink');
984 $supplemental['replace-closedpostboxesnonce'] = wp_create_nonce('closedpostboxes');
986 if ( $_POST['post_type'] == 'post' )
987 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-post_' . $id);
988 elseif ( $_POST['post_type'] == 'page' )
989 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-page_' . $id);
993 $x = new WP_Ajax_Response( array(
994 'what' => 'autosave',
996 'data' => $id ? $data : '',
997 'supplemental' => $supplemental
1001 case 'closed-postboxes' :
1002 check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1003 $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1004 $closed = array_filter($closed);
1006 $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1007 $hidden = array_filter($hidden);
1009 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1011 if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1014 if ( ! $user = wp_get_current_user() )
1017 if ( is_array($closed) )
1018 update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1020 if ( is_array($hidden) ) {
1021 $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1022 update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1027 case 'hidden-columns' :
1028 check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1029 $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1030 $hidden = explode( ',', $_POST['hidden'] );
1031 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1033 if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1036 if ( ! $user = wp_get_current_user() )
1039 if ( is_array($hidden) )
1040 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1044 case 'menu-get-metabox' :
1045 if ( ! current_user_can( 'edit_theme_options' ) )
1048 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1050 if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1052 $callback = 'wp_nav_menu_item_post_type_meta_box';
1053 $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1054 } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1056 $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1057 $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1060 if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1061 $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] );
1063 call_user_func_array($callback, array(
1066 'id' => 'add-' . $item->name,
1067 'title' => $item->labels->name,
1068 'callback' => $callback,
1073 $markup = ob_get_clean();
1075 echo json_encode(array(
1076 'replace-id' => $type . '-' . $item->name,
1077 'markup' => $markup,
1083 case 'menu-quick-search':
1084 if ( ! current_user_can( 'edit_theme_options' ) )
1087 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1089 _wp_ajax_menu_quick_search( $_REQUEST );
1093 case 'wp-link-ajax':
1094 require_once ABSPATH . 'wp-admin/includes/internal-linking.php';
1096 check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1100 if ( isset( $_POST['search'] ) )
1101 $args['s'] = stripslashes( $_POST['search'] );
1102 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1104 $results = wp_link_query( $args );
1106 if ( ! isset( $results ) )
1109 echo json_encode( $results );
1114 case 'menu-locations-save':
1115 if ( ! current_user_can( 'edit_theme_options' ) )
1117 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1118 if ( ! isset( $_POST['menu-locations'] ) )
1120 set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1123 case 'meta-box-order':
1124 check_ajax_referer( 'meta-box-order' );
1125 $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1126 $page_columns = isset( $_POST['page_columns'] ) ? (int) $_POST['page_columns'] : 0;
1127 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1129 if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1132 if ( ! $user = wp_get_current_user() )
1136 update_user_option($user->ID, "meta-box-order_$page", $order, true);
1138 if ( $page_columns )
1139 update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1143 case 'get-permalink':
1144 check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1145 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1146 die(add_query_arg(array('preview' => 'true'), get_permalink($post_id)));
1148 case 'sample-permalink':
1149 check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1150 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1151 $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1152 $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1153 die(get_sample_permalink_html($post_id, $title, $slug));
1156 check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1158 if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1161 if ( 'page' == $_POST['post_type'] ) {
1162 if ( ! current_user_can( 'edit_page', $post_ID ) )
1163 die( __('You are not allowed to edit this page.') );
1165 if ( ! current_user_can( 'edit_post', $post_ID ) )
1166 die( __('You are not allowed to edit this post.') );
1169 set_current_screen( $_POST['screen'] );
1171 if ( $last = wp_check_post_lock( $post_ID ) ) {
1172 $last_user = get_userdata( $last );
1173 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1174 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 ) );
1180 $post = get_post( $post_ID, ARRAY_A );
1181 $post = add_magic_quotes($post); //since it is from db
1183 $data['content'] = $post['post_content'];
1184 $data['excerpt'] = $post['post_excerpt'];
1187 $data['user_ID'] = $GLOBALS['user_ID'];
1189 if ( isset($data['post_parent']) )
1190 $data['parent_id'] = $data['post_parent'];
1193 if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1194 $data['post_status'] = 'private';
1196 $data['post_status'] = $data['_status'];
1198 if ( empty($data['comment_status']) )
1199 $data['comment_status'] = 'closed';
1200 if ( empty($data['ping_status']) )
1201 $data['ping_status'] = 'closed';
1206 $wp_list_table = _get_list_table('WP_Posts_List_Table');
1208 $mode = $_POST['post_view'];
1209 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ) );
1213 case 'inline-save-tax':
1214 check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1216 $taxonomy = sanitize_key( $_POST['taxonomy'] );
1217 $tax = get_taxonomy( $taxonomy );
1221 if ( ! current_user_can( $tax->cap->edit_terms ) )
1224 set_current_screen( 'edit-' . $taxonomy );
1226 $wp_list_table = _get_list_table('WP_Terms_List_Table');
1228 if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1231 $tag = get_term( $id, $taxonomy );
1232 $_POST['description'] = $tag->description;
1234 $updated = wp_update_term($id, $taxonomy, $_POST);
1235 if ( $updated && !is_wp_error($updated) ) {
1236 $tag = get_term( $updated['term_id'], $taxonomy );
1237 if ( !$tag || is_wp_error( $tag ) ) {
1238 if ( is_wp_error($tag) && $tag->get_error_message() )
1239 die( $tag->get_error_message() );
1240 die( __('Item not updated.') );
1243 echo $wp_list_table->single_row( $tag );
1245 if ( is_wp_error($updated) && $updated->get_error_message() )
1246 die( $updated->get_error_message() );
1247 die( __('Item not updated.') );
1253 check_ajax_referer( 'find-posts' );
1255 if ( empty($_POST['ps']) )
1258 if ( !empty($_POST['post_type']) && in_array( $_POST['post_type'], get_post_types() ) )
1259 $what = $_POST['post_type'];
1263 $s = stripslashes($_POST['ps']);
1264 preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches);
1265 $search_terms = array_map('_search_terms_tidy', $matches[0]);
1267 $searchand = $search = '';
1268 foreach ( (array) $search_terms as $term ) {
1269 $term = esc_sql( like_escape( $term ) );
1270 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%'))";
1271 $searchand = ' AND ';
1273 $term = esc_sql( like_escape( $s ) );
1274 if ( count($search_terms) > 1 && $search_terms[0] != $s )
1275 $search .= " OR ($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%')";
1277 $posts = $wpdb->get_results( "SELECT ID, post_title, post_status, post_date FROM $wpdb->posts WHERE post_type = '$what' AND post_status IN ('draft', 'publish') AND ($search) ORDER BY post_date_gmt DESC LIMIT 50" );
1280 $posttype = get_post_type_object($what);
1281 exit($posttype->labels->not_found);
1284 $html = '<table class="widefat" cellspacing="0"><thead><tr><th class="found-radio"><br /></th><th>'.__('Title').'</th><th>'.__('Date').'</th><th>'.__('Status').'</th></tr></thead><tbody>';
1285 foreach ( $posts as $post ) {
1287 switch ( $post->post_status ) {
1290 $stat = __('Published');
1293 $stat = __('Scheduled');
1296 $stat = __('Pending Review');
1299 $stat = __('Draft');
1303 if ( '0000-00-00 00:00:00' == $post->post_date ) {
1306 /* translators: date format in table columns, see http://php.net/date */
1307 $time = mysql2date(__('Y/m/d'), $post->post_date);
1310 $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>';
1311 $html .= '<td><label for="found-'.$post->ID.'">'.esc_html( $post->post_title ).'</label></td><td>'.esc_html( $time ).'</td><td>'.esc_html( $stat ).'</td></tr>'."\n\n";
1313 $html .= '</tbody></table>';
1315 $x = new WP_Ajax_Response();
1323 case 'widgets-order' :
1324 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1326 if ( !current_user_can('edit_theme_options') )
1329 unset( $_POST['savewidgets'], $_POST['action'] );
1331 // save widgets order for all sidebars
1332 if ( is_array($_POST['sidebars']) ) {
1333 $sidebars = array();
1334 foreach ( $_POST['sidebars'] as $key => $val ) {
1336 if ( !empty($val) ) {
1337 $val = explode(',', $val);
1338 foreach ( $val as $k => $v ) {
1339 if ( strpos($v, 'widget-') === false )
1342 $sb[$k] = substr($v, strpos($v, '_') + 1);
1345 $sidebars[$key] = $sb;
1347 wp_set_sidebars_widgets($sidebars);
1353 case 'save-widget' :
1354 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1356 if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1359 unset( $_POST['savewidgets'], $_POST['action'] );
1361 do_action('load-widgets.php');
1362 do_action('widgets.php');
1363 do_action('sidebar_admin_setup');
1365 $id_base = $_POST['id_base'];
1366 $widget_id = $_POST['widget-id'];
1367 $sidebar_id = $_POST['sidebar'];
1368 $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1369 $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1370 $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1372 $sidebars = wp_get_sidebars_widgets();
1373 $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1376 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1378 if ( !isset($wp_registered_widgets[$widget_id]) )
1381 $sidebar = array_diff( $sidebar, array($widget_id) );
1382 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1383 } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1384 if ( !$multi_number )
1387 $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1388 $widget_id = $id_base . '-' . $multi_number;
1389 $sidebar[] = $widget_id;
1391 $_POST['widget-id'] = $sidebar;
1393 foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1395 if ( $name == $id_base ) {
1396 if ( !is_callable( $control['callback'] ) )
1400 call_user_func_array( $control['callback'], $control['params'] );
1406 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1407 $sidebars[$sidebar_id] = $sidebar;
1408 wp_set_sidebars_widgets($sidebars);
1409 echo "deleted:$widget_id";
1413 if ( !empty($_POST['add_new']) )
1416 if ( $form = $wp_registered_widget_controls[$widget_id] )
1417 call_user_func_array( $form['callback'], $form['params'] );
1421 case 'image-editor':
1422 $attachment_id = intval($_POST['postid']);
1423 if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
1426 check_ajax_referer( "image_editor-$attachment_id" );
1427 include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
1430 switch ( $_POST['do'] ) {
1432 $msg = wp_save_image($attachment_id);
1433 $msg = json_encode($msg);
1437 $msg = wp_save_image($attachment_id);
1440 $msg = wp_restore_image($attachment_id);
1444 wp_image_editor($attachment_id, $msg);
1447 case 'set-post-thumbnail':
1448 $post_ID = intval( $_POST['post_id'] );
1449 if ( !current_user_can( 'edit_post', $post_ID ) )
1451 $thumbnail_id = intval( $_POST['thumbnail_id'] );
1453 check_ajax_referer( "set_post_thumbnail-$post_ID" );
1455 if ( $thumbnail_id == '-1' ) {
1456 delete_post_meta( $post_ID, '_thumbnail_id' );
1457 die( _wp_post_thumbnail_html() );
1460 if ( set_post_thumbnail( $post_ID, $thumbnail_id ) )
1461 die( _wp_post_thumbnail_html( $thumbnail_id ) );
1464 case 'date_format' :
1465 die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
1467 case 'time_format' :
1468 die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
1471 do_action( 'wp_ajax_' . $_POST['action'] );