Wordpress 3.1.3
[autoinstalls/wordpress.git] / wp-admin / admin-ajax.php
1 <?php
2 /**
3  * WordPress AJAX Process Execution.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * Executing AJAX process.
11  *
12  * @since 2.1.0
13  */
14 define('DOING_AJAX', true);
15 define('WP_ADMIN', true);
16
17 if ( ! isset( $_REQUEST['action'] ) )
18         die('-1');
19
20 require_once('../wp-load.php');
21
22 require_once('./includes/admin.php');
23 @header('Content-Type: text/html; charset=' . get_option('blog_charset'));
24 send_nosniff_header();
25
26 do_action('admin_init');
27
28 if ( ! is_user_logged_in() ) {
29
30         if ( isset( $_POST['action'] ) && $_POST['action'] == 'autosave' ) {
31                 $id = isset($_POST['post_ID'])? (int) $_POST['post_ID'] : 0;
32
33                 if ( ! $id )
34                         die('-1');
35
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(
38                         'what' => 'autosave',
39                         'id' => $id,
40                         'data' => $message
41                 ) );
42                 $x->send();
43         }
44
45         if ( !empty( $_REQUEST['action'] ) )
46                 do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
47
48         die('-1');
49 }
50
51 if ( isset( $_GET['action'] ) ) :
52 switch ( $action = $_GET['action'] ) :
53 case 'fetch-list' :
54
55         $list_class = $_GET['list_args']['class'];
56         check_ajax_referer( "fetch-list-$list_class", '_ajax_fetch_list_nonce' );
57
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;
62
63         define( 'WP_NETWORK_ADMIN', $current_screen->is_network );
64         define( 'WP_USER_ADMIN', $current_screen->is_user );
65
66         $wp_list_table = _get_list_table( $list_class );
67         if ( ! $wp_list_table )
68                 die( '0' );
69
70         if ( ! $wp_list_table->ajax_user_can() )
71                 die( '-1' );
72
73         $wp_list_table->ajax_response();
74
75         die( '0' );
76         break;
77 case 'ajax-tag-search' :
78         if ( isset( $_GET['tax'] ) ) {
79                 $taxonomy = sanitize_key( $_GET['tax'] );
80                 $tax = get_taxonomy( $taxonomy );
81                 if ( ! $tax )
82                         die( '0' );
83                 if ( ! current_user_can( $tax->cap->assign_terms ) )
84                         die( '-1' );
85         } else {
86                 die('0');
87         }
88
89         $s = stripslashes( $_GET['q'] );
90
91         if ( false !== strpos( $s, ',' ) ) {
92                 $s = explode( ',', $s );
93                 $s = $s[count( $s ) - 1];
94         }
95         $s = trim( $s );
96         if ( strlen( $s ) < 2 )
97                 die; // require 2 chars for matching
98
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 ) . '%' ) );
100
101         echo join( $results, "\n" );
102         die;
103         break;
104 case 'wp-compression-test' :
105         if ( !current_user_can( 'manage_options' ) )
106                 die('-1');
107
108         if ( ini_get('zlib.output_compression') || 'ob_gzhandler' == ini_get('output_handler') ) {
109                 update_site_option('can_compress_scripts', 0);
110                 die('0');
111         }
112
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."';
121
122                  if ( 1 == $_GET['test'] ) {
123                         echo $test_str;
124                         die;
125                  } elseif ( 2 == $_GET['test'] ) {
126                         if ( !isset($_SERVER['HTTP_ACCEPT_ENCODING']) )
127                                 die('-1');
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 );
134                         } else {
135                                 die('-1');
136                         }
137                         echo $out;
138                         die;
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);
143                 }
144         }
145
146         die('0');
147         break;
148 case 'imgedit-preview' :
149         $post_id = intval($_GET['postid']);
150         if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
151                 die('-1');
152
153         check_ajax_referer( "image_editor-$post_id" );
154
155         include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
156         if ( ! stream_preview_image($post_id) )
157                 die('-1');
158
159         die();
160         break;
161 case 'menu-quick-search':
162         if ( ! current_user_can( 'edit_theme_options' ) )
163                 die('-1');
164
165         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
166
167         _wp_ajax_menu_quick_search( $_REQUEST );
168
169         exit;
170         break;
171 case 'oembed-cache' :
172         $return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
173         die( $return );
174         break;
175 default :
176         do_action( 'wp_ajax_' . $_GET['action'] );
177         die('0');
178         break;
179 endswitch;
180 endif;
181
182 /**
183  * Sends back current comment total and new page links if they need to be updated.
184  *
185  * Contrary to normal success AJAX response ("1"), die with time() on success.
186  *
187  * @since 2.7
188  *
189  * @param int $comment_id
190  * @return die
191  */
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() );
200
201         $total += $delta;
202         if ( $total < 0 )
203                 $total = 0;
204
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 ) ) {
207                 $post_id = 0;
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'];
216                 }
217
218                 $comment_count = wp_count_comments($post_id);
219
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
223         }
224
225         $time = time(); // The time since the last comment count
226
227         $x = new WP_Ajax_Response( array(
228                 'what' => 'comment',
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 ) ),
234                         'total' => $total,
235                         'time' => $time
236                 )
237         ) );
238         $x->send();
239 }
240
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 ) )
246                 die('-1');
247         $names = explode(',', $_POST['new'.$taxonomy->name]);
248         $parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
249         if ( 0 > $parent )
250                 $parent = 0;
251         if ( $taxonomy->name == 'category' )
252                 $post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
253         else
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);
257
258         foreach ( $names as $cat_name ) {
259                 $cat_name = trim($cat_name);
260                 $category_nicename = sanitize_title($cat_name);
261                 if ( '' === $category_nicename )
262                         continue;
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'];
266                 }
267                 $checked_categories[] = $cat_id;
268                 if ( $parent ) // Do these all at once in a second
269                         continue;
270                 $category = get_term( $cat_id, $taxonomy->name );
271                 ob_start();
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();
274                 ob_end_clean();
275                 $add = array(
276                         'what' => $taxonomy->name,
277                         'id' => $cat_id,
278                         'data' => str_replace( array("\n", "\t"), '', $data),
279                         'position' => -1
280                 );
281         }
282
283         if ( $parent ) { // Foncy - replace the parent and all its children
284                 $parent = get_term( $parent, $taxonomy->name );
285                 $term_id = $parent->term_id;
286
287                 while ( $parent->parent ) { // get the top parent
288                         $parent = &get_term( $parent->parent, $taxonomy->name );
289                         if ( is_wp_error( $parent ) )
290                                 break;
291                         $term_id = $parent->term_id;
292                 }
293
294                 ob_start();
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();
297                 ob_end_clean();
298                 $add = array(
299                         'what' => $taxonomy->name,
300                         'id' => $term_id,
301                         'data' => str_replace( array("\n", "\t"), '', $data),
302                         'position' => -1
303                 );
304         }
305
306         ob_start();
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' => '&mdash; '.$taxonomy->labels->parent_item.' &mdash;'
310                 ) );
311         $sup = ob_get_contents();
312         ob_end_clean();
313         $add['supplemental'] = array( 'newcat_parent' => $sup );
314
315         $x = new WP_Ajax_Response( $add );
316         $x->send();
317 }
318
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 ) )
325                 die('-1');
326
327         check_ajax_referer( "delete-comment_$id" );
328         $status = wp_get_comment_status( $comment->comment_ID );
329
330         $delta = -1;
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
340                         $delta = 1;
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
350                         $delta = 1;
351         } elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
352                 $r = wp_delete_comment( $comment->comment_ID );
353         } else {
354                 die('-1');
355         }
356
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 );
359         die( '0' );
360         break;
361 case 'delete-tag' :
362         $tag_id = (int) $_POST['tag_ID'];
363         check_ajax_referer( "delete-tag_$tag_id" );
364
365         $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
366         $tax = get_taxonomy($taxonomy);
367
368         if ( !current_user_can( $tax->cap->delete_terms ) )
369                 die('-1');
370
371         $tag = get_term( $tag_id, $taxonomy );
372         if ( !$tag || is_wp_error( $tag ) )
373                 die('1');
374
375         if ( wp_delete_term($tag_id, $taxonomy))
376                 die('1');
377         else
378                 die('0');
379         break;
380 case 'delete-link' :
381         check_ajax_referer( "delete-bookmark_$id" );
382         if ( !current_user_can( 'manage_links' ) )
383                 die('-1');
384
385         $link = get_bookmark( $id );
386         if ( !$link || is_wp_error( $link ) )
387                 die('1');
388
389         if ( wp_delete_link( $id ) )
390                 die('1');
391         else
392                 die('0');
393         break;
394 case 'delete-meta' :
395         check_ajax_referer( "delete-meta_$id" );
396         if ( !$meta = get_post_meta_by_id( $id ) )
397                 die('1');
398
399         if ( !current_user_can( 'edit_post', $meta->post_id ) || is_protected_meta( $meta->meta_key ) )
400                 die('-1');
401         if ( delete_meta( $meta->meta_id ) )
402                 die('1');
403         die('0');
404         break;
405 case 'delete-post' :
406         check_ajax_referer( "{$action}_$id" );
407         if ( !current_user_can( 'delete_post', $id ) )
408                 die('-1');
409
410         if ( !get_post( $id ) )
411                 die('1');
412
413         if ( wp_delete_post( $id ) )
414                 die('1');
415         else
416                 die('0');
417         break;
418 case 'trash-post' :
419 case 'untrash-post' :
420         check_ajax_referer( "{$action}_$id" );
421         if ( !current_user_can( 'delete_post', $id ) )
422                 die('-1');
423
424         if ( !get_post( $id ) )
425                 die('1');
426
427         if ( 'trash-post' == $action )
428                 $done = wp_trash_post( $id );
429         else
430                 $done = wp_untrash_post( $id );
431
432         if ( $done )
433                 die('1');
434
435         die('0');
436         break;
437 case 'delete-page' :
438         check_ajax_referer( "{$action}_$id" );
439         if ( !current_user_can( 'delete_page', $id ) )
440                 die('-1');
441
442         if ( !get_page( $id ) )
443                 die('1');
444
445         if ( wp_delete_post( $id ) )
446                 die('1');
447         else
448                 die('0');
449         break;
450 case 'dim-comment' : // On success, die with time() instead of 1
451
452         if ( !$comment = get_comment( $id ) ) {
453                 $x = new WP_Ajax_Response( array(
454                         'what' => 'comment',
455                         'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
456                 ) );
457                 $x->send();
458         }
459
460         if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
461                 die('-1');
462
463         $current = wp_get_comment_status( $comment->comment_ID );
464         if ( $_POST['new'] == $current )
465                 die( (string) time() );
466
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 );
470         else
471                 $result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
472
473         if ( is_wp_error($result) ) {
474                 $x = new WP_Ajax_Response( array(
475                         'what' => 'comment',
476                         'id' => $result
477                 ) );
478                 $x->send();
479         }
480
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 );
483         die( '0' );
484         break;
485 case 'add-link-category' : // On the Fly
486         check_ajax_referer( $action );
487         if ( !current_user_can( 'manage_categories' ) )
488                 die('-1');
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);
494                 if ( '' === $slug )
495                         continue;
496                 if ( !$cat_id = term_exists( $cat_name, 'link_category' ) ) {
497                         $cat_id = wp_insert_term( $cat_name, 'link_category' );
498                 }
499                 $cat_id = $cat_id['term_id'];
500                 $cat_name = esc_html(stripslashes($cat_name));
501                 $x->add( array(
502                         'what' => 'link-category',
503                         'id' => $cat_id,
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>",
505                         'position' => -1
506                 ) );
507         }
508         $x->send();
509         break;
510 case 'add-tag' :
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);
515
516         if ( !current_user_can( $tax->cap->edit_terms ) )
517                 die('-1');
518
519         $x = new WP_Ajax_Response();
520
521         $tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
522
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();
527
528                 $x->add( array(
529                         'what' => 'taxonomy',
530                         'data' => new WP_Error('error', $message )
531                 ) );
532                 $x->send();
533         }
534
535         set_current_screen( $_POST['screen'] );
536
537         $wp_list_table = _get_list_table('WP_Terms_List_Table');
538
539         $level = 0;
540         if ( is_taxonomy_hierarchical($taxonomy) ) {
541                 $level = count( get_ancestors( $tag->term_id, $taxonomy ) );
542                 ob_start();
543                 $wp_list_table->single_row( $tag, $level );
544                 $noparents = ob_get_clean();
545         }
546
547         ob_start();
548         $wp_list_table->single_row( $tag );
549         $parents = ob_get_clean();
550
551         $x->add( array(
552                 'what' => 'taxonomy',
553                 'supplemental' => compact('parents', 'noparents')
554                 ) );
555         $x->add( array(
556                 'what' => 'term',
557                 'position' => $level,
558                 'supplemental' => (array) $tag
559                 ) );
560         $x->send();
561         break;
562 case 'get-tagcloud' :
563         if ( isset( $_POST['tax'] ) ) {
564                 $taxonomy = sanitize_key( $_POST['tax'] );
565                 $tax = get_taxonomy( $taxonomy );
566                 if ( ! $tax )
567                         die( '0' );
568                 if ( ! current_user_can( $tax->cap->assign_terms ) )
569                         die( '-1' );
570         } else {
571                 die('0');
572         }
573
574         $tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
575
576         if ( empty( $tags ) )
577                 die( isset( $tax->no_tagcloud ) ? $tax->no_tagcloud : __('No tags found!') );
578
579         if ( is_wp_error( $tags ) )
580                 die( $tags->get_error_message() );
581
582         foreach ( $tags as $key => $tag ) {
583                 $tags[ $key ]->link = '#';
584                 $tags[ $key ]->id = $tag->term_id;
585         }
586
587         // We need raw tag names here, so don't filter the output
588         $return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
589
590         if ( empty($return) )
591                 die('0');
592
593         echo $return;
594
595         exit;
596         break;
597 case 'get-comments' :
598         check_ajax_referer( $action );
599
600         set_current_screen( 'edit-comments' );
601
602         $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
603
604         if ( !current_user_can( 'edit_post', $post_id ) )
605                 die('-1');
606
607         $wp_list_table->prepare_items();
608
609         if ( !$wp_list_table->has_items() )
610                 die('1');
611
612         $comment_list_item = '';
613         $x = new WP_Ajax_Response();
614         foreach ( $wp_list_table->items as $comment ) {
615                 get_comment( $comment );
616                 ob_start();
617                         $wp_list_table->single_row( $comment );
618                         $comment_list_item .= ob_get_contents();
619                 ob_end_clean();
620         }
621         $x->add( array(
622                 'what' => 'comments',
623                 'data' => $comment_list_item
624         ) );
625         $x->send();
626         break;
627 case 'replyto-comment' :
628         check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
629
630         set_current_screen( 'edit-comments' );
631
632         $comment_post_ID = (int) $_POST['comment_post_ID'];
633         if ( !current_user_can( 'edit_post', $comment_post_ID ) )
634                 die('-1');
635
636         $status = $wpdb->get_var( $wpdb->prepare("SELECT post_status FROM $wpdb->posts WHERE ID = %d", $comment_post_ID) );
637
638         if ( empty($status) )
639                 die('1');
640         elseif ( in_array($status, array('draft', 'pending', 'trash') ) )
641                 die( __('Error: you are replying to a comment on a draft post.') );
642
643         $user = wp_get_current_user();
644         if ( $user->ID ) {
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
653                         }
654                 }
655         } else {
656                 die( __('Sorry, you must be logged in to reply to a comment.') );
657         }
658
659         if ( '' == $comment_content )
660                 die( __('Error: please type a comment.') );
661
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');
664
665         $comment_id = wp_new_comment( $commentdata );
666         $comment = get_comment($comment_id);
667         if ( ! $comment ) die('1');
668
669         $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
670
671         $x = new WP_Ajax_Response();
672
673         ob_start();
674                 if ( 'dashboard' == $_REQUEST['mode'] ) {
675                         require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
676                         _wp_dashboard_recent_comments_row( $comment );
677                 } else {
678                         if ( 'single' == $_REQUEST['mode'] ) {
679                                 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
680                         } else {
681                                 $wp_list_table = _get_list_table('WP_Comments_List_Table');
682                         }
683                         $wp_list_table->single_row( $comment );
684                 }
685                 $comment_list_item = ob_get_contents();
686         ob_end_clean();
687
688         $x->add( array(
689                 'what' => 'comment',
690                 'id' => $comment->comment_ID,
691                 'data' => $comment_list_item,
692                 'position' => $position
693         ));
694
695         $x->send();
696         break;
697 case 'edit-comment' :
698         check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
699
700         set_current_screen( 'edit-comments' );
701
702         $comment_post_ID = (int) $_POST['comment_post_ID'];
703         if ( ! current_user_can( 'edit_post', $comment_post_ID ) )
704                 die('-1');
705
706         if ( '' == $_POST['content'] )
707                 die( __('Error: please type a comment.') );
708
709         $comment_id = (int) $_POST['comment_ID'];
710         $_POST['comment_status'] = $_POST['status'];
711         edit_comment();
712
713         $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
714         $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
715
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' );
718
719         ob_start();
720                 $wp_list_table->single_row( get_comment( $comment_id ) );
721                 $comment_list_item = ob_get_contents();
722         ob_end_clean();
723
724         $x = new WP_Ajax_Response();
725
726         $x->add( array(
727                 'what' => 'edit_comment',
728                 'id' => $comment->comment_ID,
729                 'data' => $comment_list_item,
730                 'position' => $position
731         ));
732
733         $x->send();
734         break;
735 case 'add-menu-item' :
736         if ( ! current_user_can( 'edit_theme_options' ) )
737                 die('-1');
738
739         check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
740
741         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
742
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.
745
746         $menu_items_data = array();
747         foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
748                 if (
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'] )
752                 ) {
753                         switch( $menu_item_data['menu-item-type'] ) {
754                                 case 'post_type' :
755                                         $_object = get_post( $menu_item_data['menu-item-object-id'] );
756                                 break;
757
758                                 case 'taxonomy' :
759                                         $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
760                                 break;
761                         }
762
763                         $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
764                         $_menu_item = array_shift( $_menu_items );
765
766                         // Restore the missing menu item properties
767                         $menu_item_data['menu-item-description'] = $_menu_item->description;
768                 }
769
770                 $menu_items_data[] = $menu_item_data;
771         }
772
773         $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
774         if ( is_wp_error( $item_ids ) )
775                 die('-1');
776
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;
783                 }
784         }
785
786         if ( ! empty( $menu_items ) ) {
787                 $args = array(
788                         'after' => '',
789                         'before' => '',
790                         'link_after' => '',
791                         'link_before' => '',
792                         'walker' => new Walker_Nav_Menu_Edit,
793                 );
794                 echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
795         }
796         break;
797 case 'add-meta' :
798         check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
799         $c = 0;
800         $pid = (int) $_POST['post_id'];
801         $post = get_post( $pid );
802
803         if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
804                 if ( !current_user_can( 'edit_post', $pid ) )
805                         die('-1');
806                 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
807                         die('1');
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));
817
818                         if ( $pid = edit_post() ) {
819                                 if ( is_wp_error( $pid ) ) {
820                                         $x = new WP_Ajax_Response( array(
821                                                 'what' => 'meta',
822                                                 'data' => $pid
823                                         ) );
824                                         $x->send();
825                                 }
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.'));
829                         } else {
830                                 die('0');
831                         }
832                 } else if ( !$mid = add_meta( $pid ) ) {
833                         die(__('Please provide a custom field value.'));
834                 }
835
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(
840                         'what' => 'meta',
841                         'id' => $mid,
842                         'data' => _list_meta_row( $meta, $c ),
843                         'position' => 1,
844                         'supplemental' => array('postid' => $pid)
845                 ) );
846         } else { // Update?
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 ) )
857                         die('-1');
858                 if ( is_protected_meta( $meta->meta_key ) )
859                         die('-1');
860                 if ( $meta->meta_value != stripslashes($value) || $meta->meta_key != stripslashes($key) ) {
861                         if ( !$u = update_meta( $mid, $key, $value ) )
862                                 die('0'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
863                 }
864
865                 $key = stripslashes($key);
866                 $value = stripslashes($value);
867                 $x = new WP_Ajax_Response( array(
868                         'what' => 'meta',
869                         'id' => $mid, 'old_id' => $mid,
870                         'data' => _list_meta_row( array(
871                                 'meta_key' => $key,
872                                 'meta_value' => $value,
873                                 'meta_id' => $mid
874                         ), $c ),
875                         'position' => 0,
876                         'supplemental' => array('postid' => $meta->post_id)
877                 ) );
878         }
879         $x->send();
880         break;
881 case 'add-user' :
882         check_ajax_referer( $action );
883         if ( !current_user_can('create_users') )
884                 die('-1');
885         if ( !$user_id = add_user() )
886                 die('0');
887         elseif ( is_wp_error( $user_id ) ) {
888                 $x = new WP_Ajax_Response( array(
889                         'what' => 'user',
890                         'id' => $user_id
891                 ) );
892                 $x->send();
893         }
894         $user_object = new WP_User( $user_id );
895
896         $wp_list_table = _get_list_table('WP_Users_List_Table');
897
898         $x = new WP_Ajax_Response( array(
899                 'what' => 'user',
900                 'id' => $user_id,
901                 'data' => $wp_list_table->single_row( $user_object, '', $user_object->roles[0] ),
902                 'supplemental' => array(
903                         'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
904                         'role' => $user_object->roles[0]
905                 )
906         ) );
907         $x->send();
908         break;
909 case 'autosave' : // The name of this action is hardcoded in edit_post()
910         define( 'DOING_AUTOSAVE', true );
911
912         $nonce_age = check_ajax_referer( 'autosave', 'autosavenonce' );
913
914         $_POST['post_category'] = explode(",", $_POST['catslist']);
915         if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
916                 unset($_POST['post_category']);
917
918         $do_autosave = (bool) $_POST['autosave'];
919         $do_lock = true;
920
921         $data = '';
922         /* translators: draft saved date format, see http://php.net/date */
923         $draft_saved_date_format = __('g:i:s a');
924         /* translators: %s: date and time */
925         $message = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
926
927         $supplemental = array();
928         if ( isset($login_grace_period) )
929                 $supplemental['session_expired'] = add_query_arg( 'interim-login', 1, wp_login_url() );
930
931         $id = $revision_id = 0;
932
933         $post_ID = (int) $_POST['post_ID'];
934         $_POST['ID'] = $post_ID;
935         $post = get_post($post_ID);
936         if ( 'auto-draft' == $post->post_status )
937                 $_POST['post_status'] = 'draft';
938
939         if ( $last = wp_check_post_lock( $post->ID ) ) {
940                 $do_autosave = $do_lock = false;
941
942                 $last_user = get_userdata( $last );
943                 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
944                 $data = new WP_Error( 'locked', sprintf(
945                         $_POST['post_type'] == 'page' ? __( 'Autosave disabled: %s is currently editing this page.' ) : __( 'Autosave disabled: %s is currently editing this post.' ),
946                         esc_html( $last_user_name )
947                 ) );
948
949                 $supplemental['disable_autosave'] = 'disable';
950         }
951
952         if ( 'page' == $post->post_type ) {
953                 if ( !current_user_can('edit_page', $post_ID) )
954                         die(__('You are not allowed to edit this page.'));
955         } else {
956                 if ( !current_user_can('edit_post', $post_ID) )
957                         die(__('You are not allowed to edit this post.'));
958         }
959
960         if ( $do_autosave ) {
961                 // Drafts and auto-drafts are just overwritten by autosave
962                 if ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) {
963                         $id = edit_post();
964                 } else { // Non drafts are not overwritten.  The autosave is stored in a special post revision.
965                         $revision_id = wp_create_post_autosave( $post->ID );
966                         if ( is_wp_error($revision_id) )
967                                 $id = $revision_id;
968                         else
969                                 $id = $post->ID;
970                 }
971                 $data = $message;
972         } else {
973                 if ( isset( $_POST['auto_draft'] ) && '1' == $_POST['auto_draft'] )
974                         $id = 0; // This tells us it didn't actually save
975                 else
976                         $id = $post->ID;
977         }
978
979         if ( $do_lock && ( isset( $_POST['auto_draft'] ) && ( $_POST['auto_draft'] != '1' ) ) && $id && is_numeric($id) )
980                 wp_set_post_lock( $id );
981
982         if ( $nonce_age == 2 ) {
983                 $supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
984                 $supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
985                 $supplemental['replace-samplepermalinknonce'] = wp_create_nonce('samplepermalink');
986                 $supplemental['replace-closedpostboxesnonce'] = wp_create_nonce('closedpostboxes');
987                 if ( $id ) {
988                         if ( $_POST['post_type'] == 'post' )
989                                 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-post_' . $id);
990                         elseif ( $_POST['post_type'] == 'page' )
991                                 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-page_' . $id);
992                 }
993         }
994
995         $x = new WP_Ajax_Response( array(
996                 'what' => 'autosave',
997                 'id' => $id,
998                 'data' => $id ? $data : '',
999                 'supplemental' => $supplemental
1000         ) );
1001         $x->send();
1002         break;
1003 case 'closed-postboxes' :
1004         check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1005         $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1006         $closed = array_filter($closed);
1007
1008         $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1009         $hidden = array_filter($hidden);
1010
1011         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1012
1013         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1014                 die('-1');
1015
1016         if ( ! $user = wp_get_current_user() )
1017                 die('-1');
1018
1019         if ( is_array($closed) )
1020                 update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1021
1022         if ( is_array($hidden) ) {
1023                 $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1024                 update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1025         }
1026
1027         die('1');
1028         break;
1029 case 'hidden-columns' :
1030         check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1031         $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1032         $hidden = explode( ',', $_POST['hidden'] );
1033         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1034
1035         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1036                 die('-1');
1037
1038         if ( ! $user = wp_get_current_user() )
1039                 die('-1');
1040
1041         if ( is_array($hidden) )
1042                 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1043
1044         die('1');
1045         break;
1046 case 'menu-get-metabox' :
1047         if ( ! current_user_can( 'edit_theme_options' ) )
1048                 die('-1');
1049
1050         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1051
1052         if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1053                 $type = 'posttype';
1054                 $callback = 'wp_nav_menu_item_post_type_meta_box';
1055                 $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1056         } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1057                 $type = 'taxonomy';
1058                 $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1059                 $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1060         }
1061
1062         if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1063                 $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] );
1064                 ob_start();
1065                 call_user_func_array($callback, array(
1066                         null,
1067                         array(
1068                                 'id' => 'add-' . $item->name,
1069                                 'title' => $item->labels->name,
1070                                 'callback' => $callback,
1071                                 'args' => $item,
1072                         )
1073                 ));
1074
1075                 $markup = ob_get_clean();
1076
1077                 echo json_encode(array(
1078                         'replace-id' => $type . '-' . $item->name,
1079                         'markup' => $markup,
1080                 ));
1081         }
1082
1083         exit;
1084         break;
1085 case 'menu-quick-search':
1086         if ( ! current_user_can( 'edit_theme_options' ) )
1087                 die('-1');
1088
1089         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1090
1091         _wp_ajax_menu_quick_search( $_REQUEST );
1092
1093         exit;
1094         break;
1095 case 'wp-link-ajax':
1096         require_once ABSPATH . 'wp-admin/includes/internal-linking.php';
1097
1098         check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1099
1100         $args = array();
1101
1102         if ( isset( $_POST['search'] ) )
1103                 $args['s'] = stripslashes( $_POST['search'] );
1104         $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1105
1106         $results = wp_link_query( $args );
1107
1108         if ( ! isset( $results ) )
1109                 die( '0' );
1110
1111         echo json_encode( $results );
1112         echo "\n";
1113
1114         exit;
1115         break;
1116 case 'menu-locations-save':
1117         if ( ! current_user_can( 'edit_theme_options' ) )
1118                 die('-1');
1119         check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1120         if ( ! isset( $_POST['menu-locations'] ) )
1121                 die('0');
1122         set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1123         die('1');
1124         break;
1125 case 'meta-box-order':
1126         check_ajax_referer( 'meta-box-order' );
1127         $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1128         $page_columns = isset( $_POST['page_columns'] ) ? (int) $_POST['page_columns'] : 0;
1129         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1130
1131         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1132                 die('-1');
1133
1134         if ( ! $user = wp_get_current_user() )
1135                 die('-1');
1136
1137         if ( $order )
1138                 update_user_option($user->ID, "meta-box-order_$page", $order, true);
1139
1140         if ( $page_columns )
1141                 update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1142
1143         die('1');
1144         break;
1145 case 'get-permalink':
1146         check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1147         $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1148         die(add_query_arg(array('preview' => 'true'), get_permalink($post_id)));
1149 break;
1150 case 'sample-permalink':
1151         check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1152         $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1153         $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1154         $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1155         die(get_sample_permalink_html($post_id, $title, $slug));
1156 break;
1157 case 'inline-save':
1158         check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1159
1160         if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1161                 exit;
1162
1163         if ( 'page' == $_POST['post_type'] ) {
1164                 if ( ! current_user_can( 'edit_page', $post_ID ) )
1165                         die( __('You are not allowed to edit this page.') );
1166         } else {
1167                 if ( ! current_user_can( 'edit_post', $post_ID ) )
1168                         die( __('You are not allowed to edit this post.') );
1169         }
1170
1171         set_current_screen( $_POST['screen'] );
1172
1173         if ( $last = wp_check_post_lock( $post_ID ) ) {
1174                 $last_user = get_userdata( $last );
1175                 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1176                 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 ) );
1177                 exit;
1178         }
1179
1180         $data = &$_POST;
1181
1182         $post = get_post( $post_ID, ARRAY_A );
1183         $post = add_magic_quotes($post); //since it is from db
1184
1185         $data['content'] = $post['post_content'];
1186         $data['excerpt'] = $post['post_excerpt'];
1187
1188         // rename
1189         $data['user_ID'] = $GLOBALS['user_ID'];
1190
1191         if ( isset($data['post_parent']) )
1192                 $data['parent_id'] = $data['post_parent'];
1193
1194         // status
1195         if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1196                 $data['post_status'] = 'private';
1197         else
1198                 $data['post_status'] = $data['_status'];
1199
1200         if ( empty($data['comment_status']) )
1201                 $data['comment_status'] = 'closed';
1202         if ( empty($data['ping_status']) )
1203                 $data['ping_status'] = 'closed';
1204
1205         // update the post
1206         edit_post();
1207
1208         $wp_list_table = _get_list_table('WP_Posts_List_Table');
1209
1210         $mode = $_POST['post_view'];
1211         $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ) );
1212
1213         exit;
1214         break;
1215 case 'inline-save-tax':
1216         check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1217
1218         $taxonomy = sanitize_key( $_POST['taxonomy'] );
1219         $tax = get_taxonomy( $taxonomy );
1220         if ( ! $tax )
1221                 die( '0' );
1222
1223         if ( ! current_user_can( $tax->cap->edit_terms ) )
1224                 die( '-1' );
1225
1226         set_current_screen( 'edit-' . $taxonomy );
1227
1228         $wp_list_table = _get_list_table('WP_Terms_List_Table');
1229
1230         if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1231                 die(-1);
1232
1233         $tag = get_term( $id, $taxonomy );
1234         $_POST['description'] = $tag->description;
1235
1236         $updated = wp_update_term($id, $taxonomy, $_POST);
1237         if ( $updated && !is_wp_error($updated) ) {
1238                 $tag = get_term( $updated['term_id'], $taxonomy );
1239                 if ( !$tag || is_wp_error( $tag ) ) {
1240                         if ( is_wp_error($tag) && $tag->get_error_message() )
1241                                 die( $tag->get_error_message() );
1242                         die( __('Item not updated.') );
1243                 }
1244
1245                 echo $wp_list_table->single_row( $tag );
1246         } else {
1247                 if ( is_wp_error($updated) && $updated->get_error_message() )
1248                         die( $updated->get_error_message() );
1249                 die( __('Item not updated.') );
1250         }
1251
1252         exit;
1253         break;
1254 case 'find_posts':
1255         check_ajax_referer( 'find-posts' );
1256
1257         if ( empty($_POST['ps']) )
1258                 exit;
1259
1260         if ( !empty($_POST['post_type']) && in_array( $_POST['post_type'], get_post_types() ) )
1261                 $what = $_POST['post_type'];
1262         else
1263                 $what = 'post';
1264
1265         $s = stripslashes($_POST['ps']);
1266         preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches);
1267         $search_terms = array_map('_search_terms_tidy', $matches[0]);
1268
1269         $searchand = $search = '';
1270         foreach ( (array) $search_terms as $term ) {
1271                 $term = esc_sql( like_escape( $term ) );
1272                 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%'))";
1273                 $searchand = ' AND ';
1274         }
1275         $term = esc_sql( like_escape( $s ) );
1276         if ( count($search_terms) > 1 && $search_terms[0] != $s )
1277                 $search .= " OR ($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%')";
1278
1279         $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
1281         if ( ! $posts ) {
1282                 $posttype = get_post_type_object($what);
1283                 exit($posttype->labels->not_found);
1284         }
1285
1286         $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>';
1287         foreach ( $posts as $post ) {
1288
1289                 switch ( $post->post_status ) {
1290                         case 'publish' :
1291                         case 'private' :
1292                                 $stat = __('Published');
1293                                 break;
1294                         case 'future' :
1295                                 $stat = __('Scheduled');
1296                                 break;
1297                         case 'pending' :
1298                                 $stat = __('Pending Review');
1299                                 break;
1300                         case 'draft' :
1301                                 $stat = __('Draft');
1302                                 break;
1303                 }
1304
1305                 if ( '0000-00-00 00:00:00' == $post->post_date ) {
1306                         $time = '';
1307                 } else {
1308                         /* translators: date format in table columns, see http://php.net/date */
1309                         $time = mysql2date(__('Y/m/d'), $post->post_date);
1310                 }
1311
1312                 $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>';
1313                 $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";
1314         }
1315         $html .= '</tbody></table>';
1316
1317         $x = new WP_Ajax_Response();
1318         $x->add( array(
1319                 'what' => $what,
1320                 'data' => $html
1321         ));
1322         $x->send();
1323
1324         break;
1325 case 'widgets-order' :
1326         check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1327
1328         if ( !current_user_can('edit_theme_options') )
1329                 die('-1');
1330
1331         unset( $_POST['savewidgets'], $_POST['action'] );
1332
1333         // save widgets order for all sidebars
1334         if ( is_array($_POST['sidebars']) ) {
1335                 $sidebars = array();
1336                 foreach ( $_POST['sidebars'] as $key => $val ) {
1337                         $sb = array();
1338                         if ( !empty($val) ) {
1339                                 $val = explode(',', $val);
1340                                 foreach ( $val as $k => $v ) {
1341                                         if ( strpos($v, 'widget-') === false )
1342                                                 continue;
1343
1344                                         $sb[$k] = substr($v, strpos($v, '_') + 1);
1345                                 }
1346                         }
1347                         $sidebars[$key] = $sb;
1348                 }
1349                 wp_set_sidebars_widgets($sidebars);
1350                 die('1');
1351         }
1352
1353         die('-1');
1354         break;
1355 case 'save-widget' :
1356         check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1357
1358         if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1359                 die('-1');
1360
1361         unset( $_POST['savewidgets'], $_POST['action'] );
1362
1363         do_action('load-widgets.php');
1364         do_action('widgets.php');
1365         do_action('sidebar_admin_setup');
1366
1367         $id_base = $_POST['id_base'];
1368         $widget_id = $_POST['widget-id'];
1369         $sidebar_id = $_POST['sidebar'];
1370         $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1371         $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1372         $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1373
1374         $sidebars = wp_get_sidebars_widgets();
1375         $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1376
1377         // delete
1378         if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1379
1380                 if ( !isset($wp_registered_widgets[$widget_id]) )
1381                         die($error);
1382
1383                 $sidebar = array_diff( $sidebar, array($widget_id) );
1384                 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1385         } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1386                 if ( !$multi_number )
1387                         die($error);
1388
1389                 $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1390                 $widget_id = $id_base . '-' . $multi_number;
1391                 $sidebar[] = $widget_id;
1392         }
1393         $_POST['widget-id'] = $sidebar;
1394
1395         foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1396
1397                 if ( $name == $id_base ) {
1398                         if ( !is_callable( $control['callback'] ) )
1399                                 continue;
1400
1401                         ob_start();
1402                                 call_user_func_array( $control['callback'], $control['params'] );
1403                         ob_end_clean();
1404                         break;
1405                 }
1406         }
1407
1408         if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1409                 $sidebars[$sidebar_id] = $sidebar;
1410                 wp_set_sidebars_widgets($sidebars);
1411                 echo "deleted:$widget_id";
1412                 die();
1413         }
1414
1415         if ( !empty($_POST['add_new']) )
1416                 die();
1417
1418         if ( $form = $wp_registered_widget_controls[$widget_id] )
1419                 call_user_func_array( $form['callback'], $form['params'] );
1420
1421         die();
1422         break;
1423 case 'image-editor':
1424         $attachment_id = intval($_POST['postid']);
1425         if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
1426                 die('-1');
1427
1428         check_ajax_referer( "image_editor-$attachment_id" );
1429         include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
1430
1431         $msg = false;
1432         switch ( $_POST['do'] ) {
1433                 case 'save' :
1434                         $msg = wp_save_image($attachment_id);
1435                         $msg = json_encode($msg);
1436                         die($msg);
1437                         break;
1438                 case 'scale' :
1439                         $msg = wp_save_image($attachment_id);
1440                         break;
1441                 case 'restore' :
1442                         $msg = wp_restore_image($attachment_id);
1443                         break;
1444         }
1445
1446         wp_image_editor($attachment_id, $msg);
1447         die();
1448         break;
1449 case 'set-post-thumbnail':
1450         $post_ID = intval( $_POST['post_id'] );
1451         if ( !current_user_can( 'edit_post', $post_ID ) )
1452                 die( '-1' );
1453         $thumbnail_id = intval( $_POST['thumbnail_id'] );
1454
1455         check_ajax_referer( "set_post_thumbnail-$post_ID" );
1456
1457         if ( $thumbnail_id == '-1' ) {
1458                 delete_post_meta( $post_ID, '_thumbnail_id' );
1459                 die( _wp_post_thumbnail_html() );
1460         }
1461
1462         if ( set_post_thumbnail( $post_ID, $thumbnail_id ) )
1463                 die( _wp_post_thumbnail_html( $thumbnail_id ) );
1464         die( '0' );
1465         break;
1466 case 'date_format' :
1467         die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
1468         break;
1469 case 'time_format' :
1470         die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
1471         break;
1472 default :
1473         do_action( 'wp_ajax_' . $_POST['action'] );
1474         die('0');
1475         break;
1476 endswitch;
1477 ?>