3 * WordPress Core Ajax Handlers.
6 * @subpackage Administration
10 * No-privilege Ajax handlers.
13 function wp_ajax_nopriv_autosave() {
14 $id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
19 $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() );
20 $x = new WP_Ajax_Response( array(
29 * GET-based Ajax handlers.
31 function wp_ajax_fetch_list() {
32 global $wp_list_table;
34 $list_class = $_GET['list_args']['class'];
35 check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' );
37 $wp_list_table = _get_list_table( $list_class, array( 'screen' => $_GET['list_args']['screen']['id'] ) );
38 if ( ! $wp_list_table )
41 if ( ! $wp_list_table->ajax_user_can() )
44 $wp_list_table->ajax_response();
48 function wp_ajax_ajax_tag_search() {
51 if ( isset( $_GET['tax'] ) ) {
52 $taxonomy = sanitize_key( $_GET['tax'] );
53 $tax = get_taxonomy( $taxonomy );
56 if ( ! current_user_can( $tax->cap->assign_terms ) )
62 $s = stripslashes( $_GET['q'] );
64 $comma = _x( ',', 'tag delimiter' );
66 $s = str_replace( $comma, ',', $s );
67 if ( false !== strpos( $s, ',' ) ) {
68 $s = explode( ',', $s );
69 $s = $s[count( $s ) - 1];
72 if ( strlen( $s ) < 2 )
73 wp_die(); // require 2 chars for matching
75 $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 ) . '%' ) );
77 echo join( $results, "\n" );
81 function wp_ajax_wp_compression_test() {
82 if ( !current_user_can( 'manage_options' ) )
85 if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) {
86 update_site_option('can_compress_scripts', 0);
90 if ( isset($_GET['test']) ) {
91 header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
92 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
93 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
94 header( 'Pragma: no-cache' );
95 header('Content-Type: application/x-javascript; charset=UTF-8');
96 $force_gzip = ( defined('ENFORCE_GZIP') && ENFORCE_GZIP );
97 $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."';
99 if ( 1 == $_GET['test'] ) {
102 } elseif ( 2 == $_GET['test'] ) {
103 if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
105 if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') && ! $force_gzip ) {
106 header('Content-Encoding: deflate');
107 $out = gzdeflate( $test_str, 1 );
108 } elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) {
109 header('Content-Encoding: gzip');
110 $out = gzencode( $test_str, 1 );
116 } elseif ( 'no' == $_GET['test'] ) {
117 update_site_option('can_compress_scripts', 0);
118 } elseif ( 'yes' == $_GET['test'] ) {
119 update_site_option('can_compress_scripts', 1);
126 function wp_ajax_imgedit_preview() {
127 $post_id = intval($_GET['postid']);
128 if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
131 check_ajax_referer( "image_editor-$post_id" );
133 include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
134 if ( ! stream_preview_image($post_id) )
140 function wp_ajax_oembed_cache() {
143 $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
147 function wp_ajax_autocomplete_user() {
148 if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) )
151 if ( ! is_super_admin() && ! apply_filters( 'autocomplete_users_for_site_admins', false ) )
156 // Check the type of request
157 if ( isset( $_REQUEST['autocomplete_type'] ) )
158 $type = $_REQUEST['autocomplete_type'];
162 // Exclude current users of this blog
163 if ( isset( $_REQUEST['site_id'] ) )
164 $id = absint( $_REQUEST['site_id'] );
166 $id = get_current_blog_id();
168 $include_blog_users = ( $type == 'search' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
169 $exclude_blog_users = ( $type == 'add' ? get_users( array( 'blog_id' => $id, 'fields' => 'ID' ) ) : array() );
171 $users = get_users( array(
173 'search' => '*' . $_REQUEST['term'] . '*',
174 'include' => $include_blog_users,
175 'exclude' => $exclude_blog_users,
176 'search_columns' => array( 'user_login', 'user_nicename', 'user_email' ),
179 foreach ( $users as $user ) {
181 /* translators: 1: user_login, 2: user_email */
182 'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
183 'value' => $user->user_login,
187 wp_die( json_encode( $return ) );
190 function wp_ajax_dashboard_widgets() {
191 require_once ABSPATH . 'wp-admin/includes/dashboard.php';
193 switch ( $_GET['widget'] ) {
194 case 'dashboard_incoming_links' :
195 wp_dashboard_incoming_links();
197 case 'dashboard_primary' :
198 wp_dashboard_primary();
200 case 'dashboard_secondary' :
201 wp_dashboard_secondary();
203 case 'dashboard_plugins' :
204 wp_dashboard_plugins();
210 function wp_ajax_logged_in() {
219 * Sends back current comment total and new page links if they need to be updated.
221 * Contrary to normal success AJAX response ("1"), die with time() on success.
225 * @param int $comment_id
228 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
229 $total = (int) @$_POST['_total'];
230 $per_page = (int) @$_POST['_per_page'];
231 $page = (int) @$_POST['_page'];
232 $url = esc_url_raw( @$_POST['_url'] );
233 // JS didn't send us everything we need to know. Just die with success message
234 if ( !$total || !$per_page || !$page || !$url )
241 // Only do the expensive stuff on a page-break, and about 1 other time per page
242 if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
244 $status = 'total_comments'; // What type of comment count are we looking for?
245 $parsed = parse_url( $url );
246 if ( isset( $parsed['query'] ) ) {
247 parse_str( $parsed['query'], $query_vars );
248 if ( !empty( $query_vars['comment_status'] ) )
249 $status = $query_vars['comment_status'];
250 if ( !empty( $query_vars['p'] ) )
251 $post_id = (int) $query_vars['p'];
254 $comment_count = wp_count_comments($post_id);
256 if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count
257 $total = $comment_count->$status;
258 // else use the decremented value from above
261 $time = time(); // The time since the last comment count
263 $x = new WP_Ajax_Response( array(
265 'id' => $comment_id, // here for completeness - not used
266 'supplemental' => array(
267 'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
268 'total_pages' => ceil( $total / $per_page ),
269 'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
278 * POST-based Ajax handlers.
281 function _wp_ajax_add_hierarchical_term() {
282 $action = $_POST['action'];
283 $taxonomy = get_taxonomy(substr($action, 4));
284 check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
285 if ( !current_user_can( $taxonomy->cap->edit_terms ) )
287 $names = explode(',', $_POST['new'.$taxonomy->name]);
288 $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
291 if ( $taxonomy->name == 'category' )
292 $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
294 $post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array();
295 $checked_categories = array_map( 'absint', (array) $post_category );
296 $popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false);
298 foreach ( $names as $cat_name ) {
299 $cat_name = trim($cat_name);
300 $category_nicename = sanitize_title($cat_name);
301 if ( '' === $category_nicename )
303 if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) )
304 $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
305 if ( is_wp_error( $cat_id ) )
307 else if ( is_array( $cat_id ) )
308 $cat_id = $cat_id['term_id'];
309 $checked_categories[] = $cat_id;
310 if ( $parent ) // Do these all at once in a second
313 wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids ));
314 $data = ob_get_contents();
317 'what' => $taxonomy->name,
319 'data' => str_replace( array("\n", "\t"), '', $data),
324 if ( $parent ) { // Foncy - replace the parent and all its children
325 $parent = get_term( $parent, $taxonomy->name );
326 $term_id = $parent->term_id;
328 while ( $parent->parent ) { // get the top parent
329 $parent = get_term( $parent->parent, $taxonomy->name );
330 if ( is_wp_error( $parent ) )
332 $term_id = $parent->term_id;
336 wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids));
337 $data = ob_get_contents();
340 'what' => $taxonomy->name,
342 'data' => str_replace( array("\n", "\t"), '', $data),
348 wp_dropdown_categories( array(
349 'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name',
350 'hierarchical' => 1, 'show_option_none' => '— '.$taxonomy->labels->parent_item.' —'
352 $sup = ob_get_contents();
354 $add['supplemental'] = array( 'newcat_parent' => $sup );
356 $x = new WP_Ajax_Response( $add );
360 function wp_ajax_delete_comment() {
361 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
363 if ( !$comment = get_comment( $id ) )
365 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
368 check_ajax_referer( "delete-comment_$id" );
369 $status = wp_get_comment_status( $comment->comment_ID );
372 if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
373 if ( 'trash' == $status )
375 $r = wp_trash_comment( $comment->comment_ID );
376 } elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
377 if ( 'trash' != $status )
379 $r = wp_untrash_comment( $comment->comment_ID );
380 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
382 } elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
383 if ( 'spam' == $status )
385 $r = wp_spam_comment( $comment->comment_ID );
386 } elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
387 if ( 'spam' != $status )
389 $r = wp_unspam_comment( $comment->comment_ID );
390 if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
392 } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
393 $r = wp_delete_comment( $comment->comment_ID );
398 if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts
399 _wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
403 function wp_ajax_delete_tag() {
404 $tag_id = (int) $_POST['tag_ID'];
405 check_ajax_referer( "delete-tag_$tag_id" );
407 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
408 $tax = get_taxonomy($taxonomy);
410 if ( !current_user_can( $tax->cap->delete_terms ) )
413 $tag = get_term( $tag_id, $taxonomy );
414 if ( !$tag || is_wp_error( $tag ) )
417 if ( wp_delete_term($tag_id, $taxonomy))
423 function wp_ajax_delete_link() {
424 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
426 check_ajax_referer( "delete-bookmark_$id" );
427 if ( !current_user_can( 'manage_links' ) )
430 $link = get_bookmark( $id );
431 if ( !$link || is_wp_error( $link ) )
434 if ( wp_delete_link( $id ) )
440 function wp_ajax_delete_meta() {
441 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
443 check_ajax_referer( "delete-meta_$id" );
444 if ( !$meta = get_metadata_by_mid( 'post', $id ) )
447 if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $meta->post_id, $meta->meta_key ) )
449 if ( delete_meta( $meta->meta_id ) )
454 function wp_ajax_delete_post( $action ) {
455 if ( empty( $action ) )
456 $action = 'delete-post';
457 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
459 check_ajax_referer( "{$action}_$id" );
460 if ( !current_user_can( 'delete_post', $id ) )
463 if ( !get_post( $id ) )
466 if ( wp_delete_post( $id ) )
472 function wp_ajax_trash_post( $action ) {
473 if ( empty( $action ) )
474 $action = 'trash-post';
475 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
477 check_ajax_referer( "{$action}_$id" );
478 if ( !current_user_can( 'delete_post', $id ) )
481 if ( !get_post( $id ) )
484 if ( 'trash-post' == $action )
485 $done = wp_trash_post( $id );
487 $done = wp_untrash_post( $id );
495 function wp_ajax_untrash_post( $action ) {
496 if ( empty( $action ) )
497 $action = 'untrash-post';
498 wp_ajax_trash_post( $action );
501 function wp_ajax_delete_page( $action ) {
502 if ( empty( $action ) )
503 $action = 'delete-page';
504 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
506 check_ajax_referer( "{$action}_$id" );
507 if ( !current_user_can( 'delete_page', $id ) )
510 if ( ! get_post( $id ) )
513 if ( wp_delete_post( $id ) )
519 function wp_ajax_dim_comment() {
520 $id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
522 if ( !$comment = get_comment( $id ) ) {
523 $x = new WP_Ajax_Response( array(
525 'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
530 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) )
533 $current = wp_get_comment_status( $comment->comment_ID );
534 if ( $_POST['new'] == $current )
537 check_ajax_referer( "approve-comment_$id" );
538 if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
539 $result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
541 $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
543 if ( is_wp_error($result) ) {
544 $x = new WP_Ajax_Response( array(
551 // Decide if we need to send back '1' or a more complicated response including page links and comment counts
552 _wp_ajax_delete_comment_response( $comment->comment_ID );
556 function wp_ajax_add_link_category( $action ) {
557 if ( empty( $action ) )
558 $action = 'add-link-category';
559 check_ajax_referer( $action );
560 if ( !current_user_can( 'manage_categories' ) )
562 $names = explode(',', $_POST['newcat']);
563 $x = new WP_Ajax_Response();
564 foreach ( $names as $cat_name ) {
565 $cat_name = trim($cat_name);
566 $slug = sanitize_title($cat_name);
569 if ( !$cat_id = term_exists( $cat_name, 'link_category' ) )
570 $cat_id = wp_insert_term( $cat_name, 'link_category' );
571 if ( is_wp_error( $cat_id ) )
573 else if ( is_array( $cat_id ) )
574 $cat_id = $cat_id['term_id'];
575 $cat_name = esc_html(stripslashes($cat_name));
577 'what' => 'link-category',
579 '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>",
586 function wp_ajax_add_tag() {
587 global $wp_list_table;
589 check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
590 $post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
591 $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
592 $tax = get_taxonomy($taxonomy);
594 if ( !current_user_can( $tax->cap->edit_terms ) )
597 $x = new WP_Ajax_Response();
599 $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
601 if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) {
602 $message = __('An error has occurred. Please reload the page and try again.');
603 if ( is_wp_error($tag) && $tag->get_error_message() )
604 $message = $tag->get_error_message();
607 'what' => 'taxonomy',
608 'data' => new WP_Error('error', $message )
613 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
616 if ( is_taxonomy_hierarchical($taxonomy) ) {
617 $level = count( get_ancestors( $tag->term_id, $taxonomy ) );
619 $wp_list_table->single_row( $tag, $level );
620 $noparents = ob_get_clean();
624 $wp_list_table->single_row( $tag );
625 $parents = ob_get_clean();
628 'what' => 'taxonomy',
629 'supplemental' => compact('parents', 'noparents')
633 'position' => $level,
634 'supplemental' => (array) $tag
639 function wp_ajax_get_tagcloud() {
640 if ( isset( $_POST['tax'] ) ) {
641 $taxonomy = sanitize_key( $_POST['tax'] );
642 $tax = get_taxonomy( $taxonomy );
645 if ( ! current_user_can( $tax->cap->assign_terms ) )
651 $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
653 if ( empty( $tags ) )
654 wp_die( isset( $tax->no_tagcloud ) ? $tax->no_tagcloud : __('No tags found!') );
656 if ( is_wp_error( $tags ) )
657 wp_die( $tags->get_error_message() );
659 foreach ( $tags as $key => $tag ) {
660 $tags[ $key ]->link = '#';
661 $tags[ $key ]->id = $tag->term_id;
664 // We need raw tag names here, so don't filter the output
665 $return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
667 if ( empty($return) )
675 function wp_ajax_get_comments( $action ) {
676 global $wp_list_table, $post_id;
677 if ( empty( $action ) )
678 $action = 'get-comments';
680 check_ajax_referer( $action );
682 $wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
684 if ( !current_user_can( 'edit_post', $post_id ) )
687 $wp_list_table->prepare_items();
689 if ( !$wp_list_table->has_items() )
692 $x = new WP_Ajax_Response();
694 foreach ( $wp_list_table->items as $comment ) {
695 if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
697 get_comment( $comment );
698 $wp_list_table->single_row( $comment );
700 $comment_list_item = ob_get_contents();
704 'what' => 'comments',
705 'data' => $comment_list_item
710 function wp_ajax_replyto_comment( $action ) {
711 global $wp_list_table, $wpdb;
712 if ( empty( $action ) )
713 $action = 'replyto-comment';
715 check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
717 $comment_post_ID = (int) $_POST['comment_post_ID'];
718 if ( !current_user_can( 'edit_post', $comment_post_ID ) )
721 $status = $wpdb->get_var( $wpdb->prepare("SELECT post_status FROM $wpdb->posts WHERE ID = %d", $comment_post_ID) );
723 if ( empty($status) )
725 elseif ( in_array($status, array('draft', 'pending', 'trash') ) )
726 wp_die( __('ERROR: you are replying to a comment on a draft post.') );
728 $user = wp_get_current_user();
729 if ( $user->exists() ) {
730 $user_ID = $user->ID;
731 $comment_author = $wpdb->escape($user->display_name);
732 $comment_author_email = $wpdb->escape($user->user_email);
733 $comment_author_url = $wpdb->escape($user->user_url);
734 $comment_content = trim($_POST['content']);
735 if ( current_user_can( 'unfiltered_html' ) ) {
736 if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
737 kses_remove_filters(); // start with a clean slate
738 kses_init_filters(); // set up the filters
742 wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
745 if ( '' == $comment_content )
746 wp_die( __( 'ERROR: please type a comment.' ) );
748 $comment_parent = absint($_POST['comment_ID']);
749 $comment_auto_approved = false;
750 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
752 // automatically approve parent comment
753 if ( !empty($_POST['approve_parent']) ) {
754 $parent = get_comment( $comment_parent );
756 if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
757 if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
758 $comment_auto_approved = true;
762 $comment_id = wp_new_comment( $commentdata );
763 $comment = get_comment($comment_id);
764 if ( ! $comment ) wp_die( 1 );
766 $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
769 if ( 'dashboard' == $_REQUEST['mode'] ) {
770 require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
771 _wp_dashboard_recent_comments_row( $comment );
773 if ( 'single' == $_REQUEST['mode'] ) {
774 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
776 $wp_list_table = _get_list_table('WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
778 $wp_list_table->single_row( $comment );
780 $comment_list_item = ob_get_contents();
785 'id' => $comment->comment_ID,
786 'data' => $comment_list_item,
787 'position' => $position
790 if ( $comment_auto_approved )
791 $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
793 $x = new WP_Ajax_Response();
794 $x->add( $response );
798 function wp_ajax_edit_comment() {
799 global $wp_list_table;
801 check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
803 $comment_id = (int) $_POST['comment_ID'];
804 if ( ! current_user_can( 'edit_comment', $comment_id ) )
807 if ( '' == $_POST['content'] )
808 wp_die( __( 'ERROR: please type a comment.' ) );
810 $_POST['comment_status'] = $_POST['status'];
813 $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
814 $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
816 $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
817 $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
819 $comment = get_comment( $comment_id );
822 $wp_list_table->single_row( $comment );
823 $comment_list_item = ob_get_contents();
826 $x = new WP_Ajax_Response();
829 'what' => 'edit_comment',
830 'id' => $comment->comment_ID,
831 'data' => $comment_list_item,
832 'position' => $position
838 function wp_ajax_add_menu_item() {
839 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
841 if ( ! current_user_can( 'edit_theme_options' ) )
844 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
846 // For performance reasons, we omit some object properties from the checklist.
847 // The following is a hacky way to restore them when adding non-custom items.
849 $menu_items_data = array();
850 foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
852 ! empty( $menu_item_data['menu-item-type'] ) &&
853 'custom' != $menu_item_data['menu-item-type'] &&
854 ! empty( $menu_item_data['menu-item-object-id'] )
856 switch( $menu_item_data['menu-item-type'] ) {
858 $_object = get_post( $menu_item_data['menu-item-object-id'] );
862 $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
866 $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
867 $_menu_item = array_shift( $_menu_items );
869 // Restore the missing menu item properties
870 $menu_item_data['menu-item-description'] = $_menu_item->description;
873 $menu_items_data[] = $menu_item_data;
876 $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
877 if ( is_wp_error( $item_ids ) )
880 $menu_items = array();
882 foreach ( (array) $item_ids as $menu_item_id ) {
883 $menu_obj = get_post( $menu_item_id );
884 if ( ! empty( $menu_obj->ID ) ) {
885 $menu_obj = wp_setup_nav_menu_item( $menu_obj );
886 $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
887 $menu_items[] = $menu_obj;
891 $walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST['menu'] );
893 if ( ! class_exists( $walker_class_name ) )
896 if ( ! empty( $menu_items ) ) {
902 'walker' => new $walker_class_name,
904 echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
908 function wp_ajax_add_meta() {
909 check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
911 $pid = (int) $_POST['post_id'];
912 $post = get_post( $pid );
914 if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
915 if ( !current_user_can( 'edit_post', $pid ) )
917 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
919 if ( $post->post_status == 'auto-draft' ) {
920 $save_POST = $_POST; // Backup $_POST
921 $_POST = array(); // Make it empty for edit_post()
922 $_POST['action'] = 'draft'; // Warning fix
923 $_POST['post_ID'] = $pid;
924 $_POST['post_type'] = $post->post_type;
925 $_POST['post_status'] = 'draft';
926 $now = current_time('timestamp', 1);
927 $_POST['post_title'] = sprintf('Draft created on %s at %s', date(get_option('date_format'), $now), date(get_option('time_format'), $now));
929 if ( $pid = edit_post() ) {
930 if ( is_wp_error( $pid ) ) {
931 $x = new WP_Ajax_Response( array(
937 $_POST = $save_POST; // Now we can restore original $_POST again
938 if ( !$mid = add_meta( $pid ) )
939 wp_die( __( 'Please provide a custom field value.' ) );
943 } else if ( !$mid = add_meta( $pid ) ) {
944 wp_die( __( 'Please provide a custom field value.' ) );
947 $meta = get_metadata_by_mid( 'post', $mid );
948 $pid = (int) $meta->post_id;
949 $meta = get_object_vars( $meta );
950 $x = new WP_Ajax_Response( array(
953 'data' => _list_meta_row( $meta, $c ),
955 'supplemental' => array('postid' => $pid)
958 $mid = (int) key( $_POST['meta'] );
959 $key = stripslashes( $_POST['meta'][$mid]['key'] );
960 $value = stripslashes( $_POST['meta'][$mid]['value'] );
961 if ( '' == trim($key) )
962 wp_die( __( 'Please provide a custom field name.' ) );
963 if ( '' == trim($value) )
964 wp_die( __( 'Please provide a custom field value.' ) );
965 if ( ! $meta = get_metadata_by_mid( 'post', $mid ) )
966 wp_die( 0 ); // if meta doesn't exist
967 if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
968 ! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
969 ! current_user_can( 'edit_post_meta', $meta->post_id, $key ) )
971 if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
972 if ( !$u = update_metadata_by_mid( 'post', $mid, $value, $key ) )
973 wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
976 $x = new WP_Ajax_Response( array(
978 'id' => $mid, 'old_id' => $mid,
979 'data' => _list_meta_row( array(
981 'meta_value' => $value,
985 'supplemental' => array('postid' => $meta->post_id)
991 function wp_ajax_add_user( $action ) {
992 global $wp_list_table;
993 if ( empty( $action ) )
994 $action = 'add-user';
996 check_ajax_referer( $action );
997 if ( ! current_user_can('create_users') )
999 if ( ! $user_id = edit_user() ) {
1001 } elseif ( is_wp_error( $user_id ) ) {
1002 $x = new WP_Ajax_Response( array(
1008 $user_object = get_userdata( $user_id );
1010 $wp_list_table = _get_list_table('WP_Users_List_Table');
1012 $role = current( $user_object->roles );
1014 $x = new WP_Ajax_Response( array(
1017 'data' => $wp_list_table->single_row( $user_object, '', $role ),
1018 'supplemental' => array(
1019 'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
1026 function wp_ajax_autosave() {
1027 global $login_grace_period;
1029 define( 'DOING_AUTOSAVE', true );
1031 $nonce_age = check_ajax_referer( 'autosave', 'autosavenonce' );
1033 $_POST['post_category'] = explode(",", $_POST['catslist']);
1034 if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
1035 unset($_POST['post_category']);
1037 $do_autosave = (bool) $_POST['autosave'];
1040 $data = $alert = '';
1041 /* translators: draft saved date format, see http://php.net/date */
1042 $draft_saved_date_format = __('g:i:s a');
1043 /* translators: %s: date and time */
1044 $message = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
1046 $supplemental = array();
1047 if ( isset($login_grace_period) )
1048 $alert .= sprintf( __('Your login has expired. Please open a new browser window and <a href="%s" target="_blank">log in again</a>. '), add_query_arg( 'interim-login', 1, wp_login_url() ) );
1050 $id = $revision_id = 0;
1052 $post_ID = (int) $_POST['post_ID'];
1053 $_POST['ID'] = $post_ID;
1054 $post = get_post($post_ID);
1055 if ( 'auto-draft' == $post->post_status )
1056 $_POST['post_status'] = 'draft';
1058 if ( $last = wp_check_post_lock( $post->ID ) ) {
1059 $do_autosave = $do_lock = false;
1061 $last_user = get_userdata( $last );
1062 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1063 $data = __( 'Autosave disabled.' );
1065 $supplemental['disable_autosave'] = 'disable';
1066 $alert .= sprintf( __( '%s is currently editing this article. If you update it, you will overwrite the changes.' ), esc_html( $last_user_name ) );
1069 if ( 'page' == $post->post_type ) {
1070 if ( !current_user_can('edit_page', $post_ID) )
1071 wp_die( __( 'You are not allowed to edit this page.' ) );
1073 if ( !current_user_can('edit_post', $post_ID) )
1074 wp_die( __( 'You are not allowed to edit this post.' ) );
1077 if ( $do_autosave ) {
1078 // Drafts and auto-drafts are just overwritten by autosave
1079 if ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) {
1081 } else { // Non drafts are not overwritten. The autosave is stored in a special post revision.
1082 $revision_id = wp_create_post_autosave( $post->ID );
1083 if ( is_wp_error($revision_id) )
1090 if ( ! empty( $_POST['auto_draft'] ) )
1091 $id = 0; // This tells us it didn't actually save
1096 if ( $do_lock && empty( $_POST['auto_draft'] ) && $id && is_numeric( $id ) ) {
1097 $lock_result = wp_set_post_lock( $id );
1098 $supplemental['active-post-lock'] = implode( ':', $lock_result );
1101 if ( $nonce_age == 2 ) {
1102 $supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
1103 $supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
1104 $supplemental['replace-samplepermalinknonce'] = wp_create_nonce('samplepermalink');
1105 $supplemental['replace-closedpostboxesnonce'] = wp_create_nonce('closedpostboxes');
1106 $supplemental['replace-_ajax_linking_nonce'] = wp_create_nonce( 'internal-linking' );
1108 if ( $_POST['post_type'] == 'post' )
1109 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-post_' . $id);
1110 elseif ( $_POST['post_type'] == 'page' )
1111 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-page_' . $id);
1115 if ( ! empty($alert) )
1116 $supplemental['alert'] = $alert;
1118 $x = new WP_Ajax_Response( array(
1119 'what' => 'autosave',
1121 'data' => $id ? $data : '',
1122 'supplemental' => $supplemental
1127 function wp_ajax_closed_postboxes() {
1128 check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1129 $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1130 $closed = array_filter($closed);
1132 $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1133 $hidden = array_filter($hidden);
1135 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1137 if ( $page != sanitize_key( $page ) )
1140 if ( ! $user = wp_get_current_user() )
1143 if ( is_array($closed) )
1144 update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1146 if ( is_array($hidden) ) {
1147 $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1148 update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1154 function wp_ajax_hidden_columns() {
1155 check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1156 $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1157 $hidden = explode( ',', $_POST['hidden'] );
1158 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1160 if ( $page != sanitize_key( $page ) )
1163 if ( ! $user = wp_get_current_user() )
1166 if ( is_array($hidden) )
1167 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1172 function wp_ajax_update_welcome_panel() {
1173 check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
1175 if ( ! current_user_can( 'edit_theme_options' ) )
1178 update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 );
1183 function wp_ajax_menu_get_metabox() {
1184 if ( ! current_user_can( 'edit_theme_options' ) )
1187 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1189 if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1191 $callback = 'wp_nav_menu_item_post_type_meta_box';
1192 $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1193 } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1195 $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1196 $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1199 if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1200 $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] );
1202 call_user_func_array($callback, array(
1205 'id' => 'add-' . $item->name,
1206 'title' => $item->labels->name,
1207 'callback' => $callback,
1212 $markup = ob_get_clean();
1214 echo json_encode(array(
1215 'replace-id' => $type . '-' . $item->name,
1216 'markup' => $markup,
1223 function wp_ajax_wp_link_ajax() {
1224 check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1228 if ( isset( $_POST['search'] ) )
1229 $args['s'] = stripslashes( $_POST['search'] );
1230 $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1232 require(ABSPATH . WPINC . '/class-wp-editor.php');
1233 $results = _WP_Editors::wp_link_query( $args );
1235 if ( ! isset( $results ) )
1238 echo json_encode( $results );
1244 function wp_ajax_menu_locations_save() {
1245 if ( ! current_user_can( 'edit_theme_options' ) )
1247 check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1248 if ( ! isset( $_POST['menu-locations'] ) )
1250 set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1254 function wp_ajax_meta_box_order() {
1255 check_ajax_referer( 'meta-box-order' );
1256 $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1257 $page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
1259 if ( $page_columns != 'auto' )
1260 $page_columns = (int) $page_columns;
1262 $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1264 if ( $page != sanitize_key( $page ) )
1267 if ( ! $user = wp_get_current_user() )
1271 update_user_option($user->ID, "meta-box-order_$page", $order, true);
1273 if ( $page_columns )
1274 update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1279 function wp_ajax_menu_quick_search() {
1280 if ( ! current_user_can( 'edit_theme_options' ) )
1283 require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1285 _wp_ajax_menu_quick_search( $_POST );
1290 function wp_ajax_get_permalink() {
1291 check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1292 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1293 wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) );
1296 function wp_ajax_sample_permalink() {
1297 check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1298 $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1299 $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1300 $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1301 wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
1304 function wp_ajax_inline_save() {
1305 global $wp_list_table;
1307 check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1309 if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1312 if ( 'page' == $_POST['post_type'] ) {
1313 if ( ! current_user_can( 'edit_page', $post_ID ) )
1314 wp_die( __( 'You are not allowed to edit this page.' ) );
1316 if ( ! current_user_can( 'edit_post', $post_ID ) )
1317 wp_die( __( 'You are not allowed to edit this post.' ) );
1320 if ( $last = wp_check_post_lock( $post_ID ) ) {
1321 $last_user = get_userdata( $last );
1322 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1323 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 ) );
1329 $post = get_post( $post_ID, ARRAY_A );
1330 $post = add_magic_quotes($post); //since it is from db
1332 $data['content'] = $post['post_content'];
1333 $data['excerpt'] = $post['post_excerpt'];
1336 $data['user_ID'] = $GLOBALS['user_ID'];
1338 if ( isset($data['post_parent']) )
1339 $data['parent_id'] = $data['post_parent'];
1342 if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1343 $data['post_status'] = 'private';
1345 $data['post_status'] = $data['_status'];
1347 if ( empty($data['comment_status']) )
1348 $data['comment_status'] = 'closed';
1349 if ( empty($data['ping_status']) )
1350 $data['ping_status'] = 'closed';
1355 $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
1357 $mode = $_POST['post_view'];
1360 $request_post = array( get_post( $_POST['post_ID'] ) );
1361 $parent = $request_post[0]->post_parent;
1363 while ( $parent > 0 ) {
1364 $parent_post = get_post( $parent );
1365 $parent = $parent_post->post_parent;
1369 $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
1374 function wp_ajax_inline_save_tax() {
1375 global $wp_list_table;
1377 check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1379 $taxonomy = sanitize_key( $_POST['taxonomy'] );
1380 $tax = get_taxonomy( $taxonomy );
1384 if ( ! current_user_can( $tax->cap->edit_terms ) )
1387 $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
1389 if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1392 $tag = get_term( $id, $taxonomy );
1393 $_POST['description'] = $tag->description;
1395 $updated = wp_update_term($id, $taxonomy, $_POST);
1396 if ( $updated && !is_wp_error($updated) ) {
1397 $tag = get_term( $updated['term_id'], $taxonomy );
1398 if ( !$tag || is_wp_error( $tag ) ) {
1399 if ( is_wp_error($tag) && $tag->get_error_message() )
1400 wp_die( $tag->get_error_message() );
1401 wp_die( __( 'Item not updated.' ) );
1404 if ( is_wp_error($updated) && $updated->get_error_message() )
1405 wp_die( $updated->get_error_message() );
1406 wp_die( __( 'Item not updated.' ) );
1409 $parent = $tag->parent;
1410 while ( $parent > 0 ) {
1411 $parent_tag = get_term( $parent, $taxonomy );
1412 $parent = $parent_tag->parent;
1415 echo $wp_list_table->single_row( $tag, $level );
1419 function wp_ajax_find_posts() {
1422 check_ajax_referer( 'find-posts' );
1424 $post_types = get_post_types( array( 'public' => true ), 'objects' );
1425 unset( $post_types['attachment'] );
1427 $s = stripslashes( $_POST['ps'] );
1428 $searchand = $search = '';
1430 'post_type' => array_keys( $post_types ),
1431 'post_status' => 'any',
1432 'posts_per_page' => 50,
1437 $posts = get_posts( $args );
1440 wp_die( __('No items found.') );
1442 $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>';
1443 foreach ( $posts as $post ) {
1444 $title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
1446 switch ( $post->post_status ) {
1449 $stat = __('Published');
1452 $stat = __('Scheduled');
1455 $stat = __('Pending Review');
1458 $stat = __('Draft');
1462 if ( '0000-00-00 00:00:00' == $post->post_date ) {
1465 /* translators: date format in table columns, see http://php.net/date */
1466 $time = mysql2date(__('Y/m/d'), $post->post_date);
1469 $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>';
1470 $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";
1473 $html .= '</tbody></table>';
1475 $x = new WP_Ajax_Response();
1482 function wp_ajax_widgets_order() {
1483 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1485 if ( !current_user_can('edit_theme_options') )
1488 unset( $_POST['savewidgets'], $_POST['action'] );
1490 // save widgets order for all sidebars
1491 if ( is_array($_POST['sidebars']) ) {
1492 $sidebars = array();
1493 foreach ( $_POST['sidebars'] as $key => $val ) {
1495 if ( !empty($val) ) {
1496 $val = explode(',', $val);
1497 foreach ( $val as $k => $v ) {
1498 if ( strpos($v, 'widget-') === false )
1501 $sb[$k] = substr($v, strpos($v, '_') + 1);
1504 $sidebars[$key] = $sb;
1506 wp_set_sidebars_widgets($sidebars);
1513 function wp_ajax_save_widget() {
1514 global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;
1516 check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1518 if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1521 unset( $_POST['savewidgets'], $_POST['action'] );
1523 do_action('load-widgets.php');
1524 do_action('widgets.php');
1525 do_action('sidebar_admin_setup');
1527 $id_base = $_POST['id_base'];
1528 $widget_id = $_POST['widget-id'];
1529 $sidebar_id = $_POST['sidebar'];
1530 $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1531 $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1532 $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1534 $sidebars = wp_get_sidebars_widgets();
1535 $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1538 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1540 if ( !isset($wp_registered_widgets[$widget_id]) )
1543 $sidebar = array_diff( $sidebar, array($widget_id) );
1544 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1545 } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1546 if ( !$multi_number )
1549 $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1550 $widget_id = $id_base . '-' . $multi_number;
1551 $sidebar[] = $widget_id;
1553 $_POST['widget-id'] = $sidebar;
1555 foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1557 if ( $name == $id_base ) {
1558 if ( !is_callable( $control['callback'] ) )
1562 call_user_func_array( $control['callback'], $control['params'] );
1568 if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1569 $sidebars[$sidebar_id] = $sidebar;
1570 wp_set_sidebars_widgets($sidebars);
1571 echo "deleted:$widget_id";
1575 if ( !empty($_POST['add_new']) )
1578 if ( $form = $wp_registered_widget_controls[$widget_id] )
1579 call_user_func_array( $form['callback'], $form['params'] );
1584 function wp_ajax_upload_attachment() {
1585 check_ajax_referer( 'media-form' );
1587 if ( ! current_user_can( 'upload_files' ) )
1590 if ( isset( $_REQUEST['post_id'] ) ) {
1591 $post_id = $_REQUEST['post_id'];
1592 if ( ! current_user_can( 'edit_post', $post_id ) )
1598 $post_data = isset( $_REQUEST['post_data'] ) ? $_REQUEST['post_data'] : array();
1600 // If the context is custom header or background, make sure the uploaded file is an image.
1601 if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
1602 $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false );
1603 if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
1604 echo json_encode( array(
1607 'message' => __( 'The uploaded file is not a valid image. Please try again.' ),
1608 'filename' => $_FILES['async-upload']['name'],
1616 $attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
1618 if ( is_wp_error( $attachment_id ) ) {
1619 echo json_encode( array(
1622 'message' => $attachment_id->get_error_message(),
1623 'filename' => $_FILES['async-upload']['name'],
1630 if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
1631 if ( 'custom-background' === $post_data['context'] )
1632 update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', $post_data['theme'] );
1634 if ( 'custom-header' === $post_data['context'] )
1635 update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
1638 if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
1641 echo json_encode( array(
1643 'data' => $attachment,
1649 function wp_ajax_image_editor() {
1650 $attachment_id = intval($_POST['postid']);
1651 if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
1654 check_ajax_referer( "image_editor-$attachment_id" );
1655 include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
1658 switch ( $_POST['do'] ) {
1660 $msg = wp_save_image($attachment_id);
1661 $msg = json_encode($msg);
1665 $msg = wp_save_image($attachment_id);
1668 $msg = wp_restore_image($attachment_id);
1672 wp_image_editor($attachment_id, $msg);
1676 function wp_ajax_set_post_thumbnail() {
1677 $json = ! empty( $_REQUEST['json'] ); // New-style request
1679 $post_ID = intval( $_POST['post_id'] );
1680 if ( ! current_user_can( 'edit_post', $post_ID ) )
1683 $thumbnail_id = intval( $_POST['thumbnail_id'] );
1686 check_ajax_referer( "update-post_$post_ID" );
1688 check_ajax_referer( "set_post_thumbnail-$post_ID" );
1690 if ( $thumbnail_id == '-1' ) {
1691 if ( delete_post_thumbnail( $post_ID ) ) {
1692 $return = _wp_post_thumbnail_html( null, $post_ID );
1693 $json ? wp_send_json_success( $return ) : wp_die( $return );
1699 if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) {
1700 $return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
1701 $json ? wp_send_json_success( $return ) : wp_die( $return );
1707 function wp_ajax_date_format() {
1708 wp_die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
1711 function wp_ajax_time_format() {
1712 wp_die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
1715 function wp_ajax_wp_fullscreen_save_post() {
1716 $post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
1718 $post = $post_type = null;
1721 $post = get_post( $post_id );
1724 $post_type = $post->post_type;
1725 elseif ( isset( $_POST['post_type'] ) && post_type_exists( $_POST['post_type'] ) )
1726 $post_type = $_POST['post_type'];
1728 check_ajax_referer('update-post_' . $post_id, '_wpnonce');
1730 $post_id = edit_post();
1732 if ( is_wp_error($post_id) ) {
1733 if ( $post_id->get_error_message() )
1734 $message = $post_id->get_error_message();
1736 $message = __('Save failed');
1738 echo json_encode( array( 'message' => $message, 'last_edited' => '' ) );
1741 $message = __('Saved.');
1745 $last_date = mysql2date( get_option('date_format'), $post->post_modified );
1746 $last_time = mysql2date( get_option('time_format'), $post->post_modified );
1748 $last_date = date_i18n( get_option('date_format') );
1749 $last_time = date_i18n( get_option('time_format') );
1752 if ( $last_id = get_post_meta($post_id, '_edit_last', true) ) {
1753 $last_user = get_userdata($last_id);
1754 $last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time );
1756 $last_edited = sprintf( __('Last edited on %1$s at %2$s'), $last_date, $last_time );
1759 echo json_encode( array( 'message' => $message, 'last_edited' => $last_edited ) );
1763 function wp_ajax_wp_remove_post_lock() {
1764 if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) )
1766 $post_id = (int) $_POST['post_ID'];
1767 if ( ! $post = get_post( $post_id ) )
1770 check_ajax_referer( 'update-post_' . $post_id );
1772 if ( ! current_user_can( 'edit_post', $post_id ) )
1775 $active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
1776 if ( $active_lock[1] != get_current_user_id() )
1779 $new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 ) + 5 ) . ':' . $active_lock[1];
1780 update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
1784 function wp_ajax_dismiss_wp_pointer() {
1785 $pointer = $_POST['pointer'];
1786 if ( $pointer != sanitize_key( $pointer ) )
1789 // check_ajax_referer( 'dismiss-pointer_' . $pointer );
1791 $dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
1793 if ( in_array( $pointer, $dismissed ) )
1796 $dismissed[] = $pointer;
1797 $dismissed = implode( ',', $dismissed );
1799 update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
1804 * Get an attachment.
1808 function wp_ajax_get_attachment() {
1809 if ( ! isset( $_REQUEST['id'] ) )
1810 wp_send_json_error();
1812 if ( ! $id = absint( $_REQUEST['id'] ) )
1813 wp_send_json_error();
1815 if ( ! $post = get_post( $id ) )
1816 wp_send_json_error();
1818 if ( 'attachment' != $post->post_type )
1819 wp_send_json_error();
1821 if ( ! current_user_can( 'upload_files' ) )
1822 wp_send_json_error();
1824 if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
1825 wp_send_json_error();
1827 wp_send_json_success( $attachment );
1831 * Query for attachments.
1835 function wp_ajax_query_attachments() {
1836 if ( ! current_user_can( 'upload_files' ) )
1837 wp_send_json_error();
1839 $query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
1840 $query = array_intersect_key( $query, array_flip( array(
1841 's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
1842 'post_parent', 'post__in', 'post__not_in',
1845 $query['post_type'] = 'attachment';
1846 $query['post_status'] = 'inherit';
1847 if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) )
1848 $query['post_status'] .= ',private';
1850 $query = new WP_Query( $query );
1852 $posts = array_map( 'wp_prepare_attachment_for_js', $query->posts );
1853 $posts = array_filter( $posts );
1855 wp_send_json_success( $posts );
1859 * Save attachment attributes.
1863 function wp_ajax_save_attachment() {
1864 if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) )
1865 wp_send_json_error();
1867 if ( ! $id = absint( $_REQUEST['id'] ) )
1868 wp_send_json_error();
1870 check_ajax_referer( 'update-post_' . $id, 'nonce' );
1872 if ( ! current_user_can( 'edit_post', $id ) )
1873 wp_send_json_error();
1875 $changes = $_REQUEST['changes'];
1876 $post = get_post( $id, ARRAY_A );
1878 if ( 'attachment' != $post['post_type'] )
1879 wp_send_json_error();
1881 if ( isset( $changes['title'] ) )
1882 $post['post_title'] = $changes['title'];
1884 if ( isset( $changes['caption'] ) )
1885 $post['post_excerpt'] = $changes['caption'];
1887 if ( isset( $changes['description'] ) )
1888 $post['post_content'] = $changes['description'];
1890 if ( isset( $changes['alt'] ) ) {
1891 $alt = get_post_meta( $id, '_wp_attachment_image_alt', true );
1892 $new_alt = stripslashes( $changes['alt'] );
1893 if ( $alt != $new_alt ) {
1894 $new_alt = wp_strip_all_tags( $new_alt, true );
1895 update_post_meta( $id, '_wp_attachment_image_alt', addslashes( $new_alt ) );
1899 wp_update_post( $post );
1900 wp_send_json_success();
1904 * Save backwards compatible attachment attributes.
1908 function wp_ajax_save_attachment_compat() {
1909 if ( ! isset( $_REQUEST['id'] ) )
1910 wp_send_json_error();
1912 if ( ! $id = absint( $_REQUEST['id'] ) )
1913 wp_send_json_error();
1915 if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) )
1916 wp_send_json_error();
1917 $attachment_data = $_REQUEST['attachments'][ $id ];
1919 check_ajax_referer( 'update-post_' . $id, 'nonce' );
1921 if ( ! current_user_can( 'edit_post', $id ) )
1922 wp_send_json_error();
1924 $post = get_post( $id, ARRAY_A );
1926 if ( 'attachment' != $post['post_type'] )
1927 wp_send_json_error();
1929 $post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
1931 if ( isset( $post['errors'] ) ) {
1932 $errors = $post['errors']; // @todo return me and display me!
1933 unset( $post['errors'] );
1936 wp_update_post( $post );
1938 foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1939 if ( isset( $attachment_data[ $taxonomy ] ) )
1940 wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
1943 if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
1944 wp_send_json_error();
1946 wp_send_json_success( $attachment );
1949 function wp_ajax_save_attachment_order() {
1950 if ( ! isset( $_REQUEST['post_id'] ) )
1951 wp_send_json_error();
1953 if ( ! $post_id = absint( $_REQUEST['post_id'] ) )
1954 wp_send_json_error();
1956 if ( empty( $_REQUEST['attachments'] ) )
1957 wp_send_json_error();
1959 check_ajax_referer( 'update-post_' . $post_id, 'nonce' );
1961 $attachments = $_REQUEST['attachments'];
1963 if ( ! current_user_can( 'edit_post', $post_id ) )
1964 wp_send_json_error();
1966 $post = get_post( $post_id, ARRAY_A );
1968 foreach ( $attachments as $attachment_id => $menu_order ) {
1969 if ( ! current_user_can( 'edit_post', $attachment_id ) )
1971 if ( ! $attachment = get_post( $attachment_id ) )
1973 if ( 'attachment' != $attachment->post_type )
1976 wp_update_post( array( 'ID' => $attachment_id, 'menu_order' => $menu_order ) );
1979 wp_send_json_success();
1983 * Generates the HTML to send an attachment to the editor.
1984 * Backwards compatible with the media_send_to_editor filter and the chain
1985 * of filters that follow.
1989 function wp_ajax_send_attachment_to_editor() {
1990 check_ajax_referer( 'media-send-to-editor', 'nonce' );
1992 $attachment = stripslashes_deep( $_POST['attachment'] );
1994 $id = intval( $attachment['id'] );
1996 if ( ! $post = get_post( $id ) )
1997 wp_send_json_error();
1999 if ( 'attachment' != $post->post_type )
2000 wp_send_json_error();
2002 if ( current_user_can( 'edit_post', $id ) ) {
2003 // If this attachment is unattached, attach it. Primarily a back compat thing.
2004 if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) {
2005 wp_update_post( array( 'ID' => $id, 'post_parent' => $insert_into_post_id ) );
2010 $html = $title = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
2011 if ( ! empty( $attachment['url'] ) ) {
2012 $url = $attachment['url'];
2013 if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url )
2014 $rel = ' rel="attachment wp-att-' . $id . '"';
2015 $html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
2018 remove_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 );
2020 if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
2021 $align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
2022 $size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
2023 $alt = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
2024 $caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
2025 $title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
2026 $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
2029 $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
2031 wp_send_json_success( $html );
2035 * Generates the HTML to send a non-image embed link to the editor.
2037 * Backwards compatible with the following filters:
2038 * - file_send_to_editor_url
2039 * - audio_send_to_editor_url
2040 * - video_send_to_editor_url
2044 function wp_ajax_send_link_to_editor() {
2045 check_ajax_referer( 'media-send-to-editor', 'nonce' );
2047 if ( ! $src = stripslashes( $_POST['src'] ) )
2048 wp_send_json_error();
2050 if ( ! strpos( $src, '://' ) )
2051 $src = 'http://' . $src;
2053 if ( ! $src = esc_url_raw( $src ) )
2054 wp_send_json_error();
2056 if ( ! $title = trim( stripslashes( $_POST['title'] ) ) )
2057 $title = wp_basename( $src );
2061 $html = '<a href="' . esc_url( $src ) . '">' . $title . '</a>';
2063 // Figure out what filter to run:
2065 if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) )
2066 && ( 'audio' == $ext_type || 'video' == $ext_type ) )
2069 $html = apply_filters( $type . '_send_to_editor_url', $html, $src, $title );
2071 wp_send_json_success( $html );