Wordpress 3.2
[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', '_wpnonce_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         $x = new WP_Ajax_Response();
613         ob_start();
614         foreach ( $wp_list_table->items as $comment ) {
615                 get_comment( $comment );
616                 $wp_list_table->single_row( $comment );
617         }
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         $comment_auto_approved = false;
664         $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
665
666         $comment_id = wp_new_comment( $commentdata );
667         $comment = get_comment($comment_id);
668         if ( ! $comment ) die('1');
669
670         $position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
671
672
673         // automatically approve parent comment
674         if ( !empty($_POST['approve_parent']) ) {
675                 $parent = get_comment( $comment_parent );
676
677                 if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
678                         if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
679                                 $comment_auto_approved = true;
680                 }
681         }
682
683         ob_start();
684                 if ( 'dashboard' == $_REQUEST['mode'] ) {
685                         require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
686                         _wp_dashboard_recent_comments_row( $comment );
687                 } else {
688                         if ( 'single' == $_REQUEST['mode'] ) {
689                                 $wp_list_table = _get_list_table('WP_Post_Comments_List_Table');
690                         } else {
691                                 $wp_list_table = _get_list_table('WP_Comments_List_Table');
692                         }
693                         $wp_list_table->single_row( $comment );
694                 }
695                 $comment_list_item = ob_get_contents();
696         ob_end_clean();
697
698         $response =  array(
699                 'what' => 'comment',
700                 'id' => $comment->comment_ID,
701                 'data' => $comment_list_item,
702                 'position' => $position
703         );
704
705         if ( $comment_auto_approved )
706                 $response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
707
708         $x = new WP_Ajax_Response();
709         $x->add( $response );
710         $x->send();
711         break;
712 case 'edit-comment' :
713         check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
714
715         set_current_screen( 'edit-comments' );
716
717         $comment_post_ID = (int) $_POST['comment_post_ID'];
718         if ( ! current_user_can( 'edit_post', $comment_post_ID ) )
719                 die('-1');
720
721         if ( '' == $_POST['content'] )
722                 die( __('Error: please type a comment.') );
723
724         $comment_id = (int) $_POST['comment_ID'];
725         $_POST['comment_status'] = $_POST['status'];
726         edit_comment();
727
728         $position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
729         $comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
730
731         $checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
732         $wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table' );
733
734         ob_start();
735                 $wp_list_table->single_row( get_comment( $comment_id ) );
736                 $comment_list_item = ob_get_contents();
737         ob_end_clean();
738
739         $x = new WP_Ajax_Response();
740
741         $x->add( array(
742                 'what' => 'edit_comment',
743                 'id' => $comment->comment_ID,
744                 'data' => $comment_list_item,
745                 'position' => $position
746         ));
747
748         $x->send();
749         break;
750 case 'add-menu-item' :
751         if ( ! current_user_can( 'edit_theme_options' ) )
752                 die('-1');
753
754         check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
755
756         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
757
758         // For performance reasons, we omit some object properties from the checklist.
759         // The following is a hacky way to restore them when adding non-custom items.
760
761         $menu_items_data = array();
762         foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
763                 if (
764                         ! empty( $menu_item_data['menu-item-type'] ) &&
765                         'custom' != $menu_item_data['menu-item-type'] &&
766                         ! empty( $menu_item_data['menu-item-object-id'] )
767                 ) {
768                         switch( $menu_item_data['menu-item-type'] ) {
769                                 case 'post_type' :
770                                         $_object = get_post( $menu_item_data['menu-item-object-id'] );
771                                 break;
772
773                                 case 'taxonomy' :
774                                         $_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
775                                 break;
776                         }
777
778                         $_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
779                         $_menu_item = array_shift( $_menu_items );
780
781                         // Restore the missing menu item properties
782                         $menu_item_data['menu-item-description'] = $_menu_item->description;
783                 }
784
785                 $menu_items_data[] = $menu_item_data;
786         }
787
788         $item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
789         if ( is_wp_error( $item_ids ) )
790                 die('-1');
791
792         foreach ( (array) $item_ids as $menu_item_id ) {
793                 $menu_obj = get_post( $menu_item_id );
794                 if ( ! empty( $menu_obj->ID ) ) {
795                         $menu_obj = wp_setup_nav_menu_item( $menu_obj );
796                         $menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
797                         $menu_items[] = $menu_obj;
798                 }
799         }
800
801         if ( ! empty( $menu_items ) ) {
802                 $args = array(
803                         'after' => '',
804                         'before' => '',
805                         'link_after' => '',
806                         'link_before' => '',
807                         'walker' => new Walker_Nav_Menu_Edit,
808                 );
809                 echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
810         }
811         break;
812 case 'add-meta' :
813         check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
814         $c = 0;
815         $pid = (int) $_POST['post_id'];
816         $post = get_post( $pid );
817
818         if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
819                 if ( !current_user_can( 'edit_post', $pid ) )
820                         die('-1');
821                 if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
822                         die('1');
823                 if ( $post->post_status == 'auto-draft' ) {
824                         $save_POST = $_POST; // Backup $_POST
825                         $_POST = array(); // Make it empty for edit_post()
826                         $_POST['action'] = 'draft'; // Warning fix
827                         $_POST['post_ID'] = $pid;
828                         $_POST['post_type'] = $post->post_type;
829                         $_POST['post_status'] = 'draft';
830                         $now = current_time('timestamp', 1);
831                         $_POST['post_title'] = sprintf('Draft created on %s at %s', date(get_option('date_format'), $now), date(get_option('time_format'), $now));
832
833                         if ( $pid = edit_post() ) {
834                                 if ( is_wp_error( $pid ) ) {
835                                         $x = new WP_Ajax_Response( array(
836                                                 'what' => 'meta',
837                                                 'data' => $pid
838                                         ) );
839                                         $x->send();
840                                 }
841                                 $_POST = $save_POST; // Now we can restore original $_POST again
842                                 if ( !$mid = add_meta( $pid ) )
843                                         die(__('Please provide a custom field value.'));
844                         } else {
845                                 die('0');
846                         }
847                 } else if ( !$mid = add_meta( $pid ) ) {
848                         die(__('Please provide a custom field value.'));
849                 }
850
851                 $meta = get_post_meta_by_id( $mid );
852                 $pid = (int) $meta->post_id;
853                 $meta = get_object_vars( $meta );
854                 $x = new WP_Ajax_Response( array(
855                         'what' => 'meta',
856                         'id' => $mid,
857                         'data' => _list_meta_row( $meta, $c ),
858                         'position' => 1,
859                         'supplemental' => array('postid' => $pid)
860                 ) );
861         } else { // Update?
862                 $mid = (int) array_pop( array_keys($_POST['meta']) );
863                 $key = $_POST['meta'][$mid]['key'];
864                 $value = $_POST['meta'][$mid]['value'];
865                 if ( '' == trim($key) )
866                         die(__('Please provide a custom field name.'));
867                 if ( '' == trim($value) )
868                         die(__('Please provide a custom field value.'));
869                 if ( !$meta = get_post_meta_by_id( $mid ) )
870                         die('0'); // if meta doesn't exist
871                 if ( !current_user_can( 'edit_post', $meta->post_id ) )
872                         die('-1');
873                 if ( is_protected_meta( $meta->meta_key ) )
874                         die('-1');
875                 if ( $meta->meta_value != stripslashes($value) || $meta->meta_key != stripslashes($key) ) {
876                         if ( !$u = update_meta( $mid, $key, $value ) )
877                                 die('0'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
878                 }
879
880                 $key = stripslashes($key);
881                 $value = stripslashes($value);
882                 $x = new WP_Ajax_Response( array(
883                         'what' => 'meta',
884                         'id' => $mid, 'old_id' => $mid,
885                         'data' => _list_meta_row( array(
886                                 'meta_key' => $key,
887                                 'meta_value' => $value,
888                                 'meta_id' => $mid
889                         ), $c ),
890                         'position' => 0,
891                         'supplemental' => array('postid' => $meta->post_id)
892                 ) );
893         }
894         $x->send();
895         break;
896 case 'add-user' :
897         check_ajax_referer( $action );
898         if ( !current_user_can('create_users') )
899                 die('-1');
900         if ( !$user_id = add_user() )
901                 die('0');
902         elseif ( is_wp_error( $user_id ) ) {
903                 $x = new WP_Ajax_Response( array(
904                         'what' => 'user',
905                         'id' => $user_id
906                 ) );
907                 $x->send();
908         }
909         $user_object = new WP_User( $user_id );
910
911         $wp_list_table = _get_list_table('WP_Users_List_Table');
912
913         $x = new WP_Ajax_Response( array(
914                 'what' => 'user',
915                 'id' => $user_id,
916                 'data' => $wp_list_table->single_row( $user_object, '', $user_object->roles[0] ),
917                 'supplemental' => array(
918                         'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
919                         'role' => $user_object->roles[0]
920                 )
921         ) );
922         $x->send();
923         break;
924 case 'autosave' : // The name of this action is hardcoded in edit_post()
925         define( 'DOING_AUTOSAVE', true );
926
927         $nonce_age = check_ajax_referer( 'autosave', 'autosavenonce' );
928
929         $_POST['post_category'] = explode(",", $_POST['catslist']);
930         if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
931                 unset($_POST['post_category']);
932
933         $do_autosave = (bool) $_POST['autosave'];
934         $do_lock = true;
935
936         $data = $alert = '';
937         /* translators: draft saved date format, see http://php.net/date */
938         $draft_saved_date_format = __('g:i:s a');
939         /* translators: %s: date and time */
940         $message = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
941
942         $supplemental = array();
943         if ( isset($login_grace_period) )
944                 $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() ) );
945
946         $id = $revision_id = 0;
947
948         $post_ID = (int) $_POST['post_ID'];
949         $_POST['ID'] = $post_ID;
950         $post = get_post($post_ID);
951         if ( 'auto-draft' == $post->post_status )
952                 $_POST['post_status'] = 'draft';
953
954         if ( $last = wp_check_post_lock( $post->ID ) ) {
955                 $do_autosave = $do_lock = false;
956
957                 $last_user = get_userdata( $last );
958                 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
959                 $data = __( 'Autosave disabled.' );
960
961                 $supplemental['disable_autosave'] = 'disable';
962                 $alert .= sprintf( __( '%s is currently editing this article. If you update it, you will overwrite the changes.' ), esc_html( $last_user_name ) );
963         }
964
965         if ( 'page' == $post->post_type ) {
966                 if ( !current_user_can('edit_page', $post_ID) )
967                         die(__('You are not allowed to edit this page.'));
968         } else {
969                 if ( !current_user_can('edit_post', $post_ID) )
970                         die(__('You are not allowed to edit this post.'));
971         }
972
973         if ( $do_autosave ) {
974                 // Drafts and auto-drafts are just overwritten by autosave
975                 if ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) {
976                         $id = edit_post();
977                 } else { // Non drafts are not overwritten.  The autosave is stored in a special post revision.
978                         $revision_id = wp_create_post_autosave( $post->ID );
979                         if ( is_wp_error($revision_id) )
980                                 $id = $revision_id;
981                         else
982                                 $id = $post->ID;
983                 }
984                 $data = $message;
985         } else {
986                 if ( isset( $_POST['auto_draft'] ) && '1' == $_POST['auto_draft'] )
987                         $id = 0; // This tells us it didn't actually save
988                 else
989                         $id = $post->ID;
990         }
991
992         if ( $do_lock && ( isset( $_POST['auto_draft'] ) && ( $_POST['auto_draft'] != '1' ) ) && $id && is_numeric($id) )
993                 wp_set_post_lock( $id );
994
995         if ( $nonce_age == 2 ) {
996                 $supplemental['replace-autosavenonce'] = wp_create_nonce('autosave');
997                 $supplemental['replace-getpermalinknonce'] = wp_create_nonce('getpermalink');
998                 $supplemental['replace-samplepermalinknonce'] = wp_create_nonce('samplepermalink');
999                 $supplemental['replace-closedpostboxesnonce'] = wp_create_nonce('closedpostboxes');
1000                 if ( $id ) {
1001                         if ( $_POST['post_type'] == 'post' )
1002                                 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-post_' . $id);
1003                         elseif ( $_POST['post_type'] == 'page' )
1004                                 $supplemental['replace-_wpnonce'] = wp_create_nonce('update-page_' . $id);
1005                 }
1006         }
1007
1008         if ( ! empty($alert) )
1009                 $supplemental['alert'] = $alert;
1010
1011         $x = new WP_Ajax_Response( array(
1012                 'what' => 'autosave',
1013                 'id' => $id,
1014                 'data' => $id ? $data : '',
1015                 'supplemental' => $supplemental
1016         ) );
1017         $x->send();
1018         break;
1019 case 'closed-postboxes' :
1020         check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
1021         $closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
1022         $closed = array_filter($closed);
1023
1024         $hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
1025         $hidden = array_filter($hidden);
1026
1027         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1028
1029         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1030                 die('-1');
1031
1032         if ( ! $user = wp_get_current_user() )
1033                 die('-1');
1034
1035         if ( is_array($closed) )
1036                 update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
1037
1038         if ( is_array($hidden) ) {
1039                 $hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
1040                 update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
1041         }
1042
1043         die('1');
1044         break;
1045 case 'hidden-columns' :
1046         check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
1047         $hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
1048         $hidden = explode( ',', $_POST['hidden'] );
1049         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1050
1051         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1052                 die('-1');
1053
1054         if ( ! $user = wp_get_current_user() )
1055                 die('-1');
1056
1057         if ( is_array($hidden) )
1058                 update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
1059
1060         die('1');
1061         break;
1062 case 'menu-get-metabox' :
1063         if ( ! current_user_can( 'edit_theme_options' ) )
1064                 die('-1');
1065
1066         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1067
1068         if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
1069                 $type = 'posttype';
1070                 $callback = 'wp_nav_menu_item_post_type_meta_box';
1071                 $items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
1072         } elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
1073                 $type = 'taxonomy';
1074                 $callback = 'wp_nav_menu_item_taxonomy_meta_box';
1075                 $items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
1076         }
1077
1078         if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
1079                 $item = apply_filters( 'nav_menu_meta_box_object', $items[ $_POST['item-object'] ] );
1080                 ob_start();
1081                 call_user_func_array($callback, array(
1082                         null,
1083                         array(
1084                                 'id' => 'add-' . $item->name,
1085                                 'title' => $item->labels->name,
1086                                 'callback' => $callback,
1087                                 'args' => $item,
1088                         )
1089                 ));
1090
1091                 $markup = ob_get_clean();
1092
1093                 echo json_encode(array(
1094                         'replace-id' => $type . '-' . $item->name,
1095                         'markup' => $markup,
1096                 ));
1097         }
1098
1099         exit;
1100         break;
1101 case 'menu-quick-search':
1102         if ( ! current_user_can( 'edit_theme_options' ) )
1103                 die('-1');
1104
1105         require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
1106
1107         _wp_ajax_menu_quick_search( $_REQUEST );
1108
1109         exit;
1110         break;
1111 case 'wp-link-ajax':
1112         require_once ABSPATH . 'wp-admin/includes/internal-linking.php';
1113
1114         check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
1115
1116         $args = array();
1117
1118         if ( isset( $_POST['search'] ) )
1119                 $args['s'] = stripslashes( $_POST['search'] );
1120         $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
1121
1122         $results = wp_link_query( $args );
1123
1124         if ( ! isset( $results ) )
1125                 die( '0' );
1126
1127         echo json_encode( $results );
1128         echo "\n";
1129
1130         exit;
1131         break;
1132 case 'menu-locations-save':
1133         if ( ! current_user_can( 'edit_theme_options' ) )
1134                 die('-1');
1135         check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
1136         if ( ! isset( $_POST['menu-locations'] ) )
1137                 die('0');
1138         set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
1139         die('1');
1140         break;
1141 case 'meta-box-order':
1142         check_ajax_referer( 'meta-box-order' );
1143         $order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
1144         $page_columns = isset( $_POST['page_columns'] ) ? (int) $_POST['page_columns'] : 0;
1145         $page = isset( $_POST['page'] ) ? $_POST['page'] : '';
1146
1147         if ( !preg_match( '/^[a-z_-]+$/', $page ) )
1148                 die('-1');
1149
1150         if ( ! $user = wp_get_current_user() )
1151                 die('-1');
1152
1153         if ( $order )
1154                 update_user_option($user->ID, "meta-box-order_$page", $order, true);
1155
1156         if ( $page_columns )
1157                 update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
1158
1159         die('1');
1160         break;
1161 case 'get-permalink':
1162         check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
1163         $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1164         die(add_query_arg(array('preview' => 'true'), get_permalink($post_id)));
1165 break;
1166 case 'sample-permalink':
1167         check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
1168         $post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
1169         $title = isset($_POST['new_title'])? $_POST['new_title'] : '';
1170         $slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
1171         die(get_sample_permalink_html($post_id, $title, $slug));
1172 break;
1173 case 'inline-save':
1174         check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
1175
1176         if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
1177                 exit;
1178
1179         if ( 'page' == $_POST['post_type'] ) {
1180                 if ( ! current_user_can( 'edit_page', $post_ID ) )
1181                         die( __('You are not allowed to edit this page.') );
1182         } else {
1183                 if ( ! current_user_can( 'edit_post', $post_ID ) )
1184                         die( __('You are not allowed to edit this post.') );
1185         }
1186
1187         set_current_screen( $_POST['screen'] );
1188
1189         if ( $last = wp_check_post_lock( $post_ID ) ) {
1190                 $last_user = get_userdata( $last );
1191                 $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
1192                 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 ) );
1193                 exit;
1194         }
1195
1196         $data = &$_POST;
1197
1198         $post = get_post( $post_ID, ARRAY_A );
1199         $post = add_magic_quotes($post); //since it is from db
1200
1201         $data['content'] = $post['post_content'];
1202         $data['excerpt'] = $post['post_excerpt'];
1203
1204         // rename
1205         $data['user_ID'] = $GLOBALS['user_ID'];
1206
1207         if ( isset($data['post_parent']) )
1208                 $data['parent_id'] = $data['post_parent'];
1209
1210         // status
1211         if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
1212                 $data['post_status'] = 'private';
1213         else
1214                 $data['post_status'] = $data['_status'];
1215
1216         if ( empty($data['comment_status']) )
1217                 $data['comment_status'] = 'closed';
1218         if ( empty($data['ping_status']) )
1219                 $data['ping_status'] = 'closed';
1220
1221         // update the post
1222         edit_post();
1223
1224         $wp_list_table = _get_list_table('WP_Posts_List_Table');
1225
1226         $mode = $_POST['post_view'];
1227         $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ) );
1228
1229         exit;
1230         break;
1231 case 'inline-save-tax':
1232         check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
1233
1234         $taxonomy = sanitize_key( $_POST['taxonomy'] );
1235         $tax = get_taxonomy( $taxonomy );
1236         if ( ! $tax )
1237                 die( '0' );
1238
1239         if ( ! current_user_can( $tax->cap->edit_terms ) )
1240                 die( '-1' );
1241
1242         set_current_screen( 'edit-' . $taxonomy );
1243
1244         $wp_list_table = _get_list_table('WP_Terms_List_Table');
1245
1246         if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
1247                 die(-1);
1248
1249         $tag = get_term( $id, $taxonomy );
1250         $_POST['description'] = $tag->description;
1251
1252         $updated = wp_update_term($id, $taxonomy, $_POST);
1253         if ( $updated && !is_wp_error($updated) ) {
1254                 $tag = get_term( $updated['term_id'], $taxonomy );
1255                 if ( !$tag || is_wp_error( $tag ) ) {
1256                         if ( is_wp_error($tag) && $tag->get_error_message() )
1257                                 die( $tag->get_error_message() );
1258                         die( __('Item not updated.') );
1259                 }
1260
1261                 echo $wp_list_table->single_row( $tag );
1262         } else {
1263                 if ( is_wp_error($updated) && $updated->get_error_message() )
1264                         die( $updated->get_error_message() );
1265                 die( __('Item not updated.') );
1266         }
1267
1268         exit;
1269         break;
1270 case 'find_posts':
1271         check_ajax_referer( 'find-posts' );
1272
1273         if ( empty($_POST['ps']) )
1274                 exit;
1275
1276         if ( !empty($_POST['post_type']) && in_array( $_POST['post_type'], get_post_types() ) )
1277                 $what = $_POST['post_type'];
1278         else
1279                 $what = 'post';
1280
1281         $s = stripslashes($_POST['ps']);
1282         preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches);
1283         $search_terms = array_map('_search_terms_tidy', $matches[0]);
1284
1285         $searchand = $search = '';
1286         foreach ( (array) $search_terms as $term ) {
1287                 $term = esc_sql( like_escape( $term ) );
1288                 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%'))";
1289                 $searchand = ' AND ';
1290         }
1291         $term = esc_sql( like_escape( $s ) );
1292         if ( count($search_terms) > 1 && $search_terms[0] != $s )
1293                 $search .= " OR ($wpdb->posts.post_title LIKE '%{$term}%') OR ($wpdb->posts.post_content LIKE '%{$term}%')";
1294
1295         $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" );
1296
1297         if ( ! $posts ) {
1298                 $posttype = get_post_type_object($what);
1299                 exit($posttype->labels->not_found);
1300         }
1301
1302         $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>';
1303         foreach ( $posts as $post ) {
1304
1305                 switch ( $post->post_status ) {
1306                         case 'publish' :
1307                         case 'private' :
1308                                 $stat = __('Published');
1309                                 break;
1310                         case 'future' :
1311                                 $stat = __('Scheduled');
1312                                 break;
1313                         case 'pending' :
1314                                 $stat = __('Pending Review');
1315                                 break;
1316                         case 'draft' :
1317                                 $stat = __('Draft');
1318                                 break;
1319                 }
1320
1321                 if ( '0000-00-00 00:00:00' == $post->post_date ) {
1322                         $time = '';
1323                 } else {
1324                         /* translators: date format in table columns, see http://php.net/date */
1325                         $time = mysql2date(__('Y/m/d'), $post->post_date);
1326                 }
1327
1328                 $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>';
1329                 $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";
1330         }
1331         $html .= '</tbody></table>';
1332
1333         $x = new WP_Ajax_Response();
1334         $x->add( array(
1335                 'what' => $what,
1336                 'data' => $html
1337         ));
1338         $x->send();
1339
1340         break;
1341 case 'widgets-order' :
1342         check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1343
1344         if ( !current_user_can('edit_theme_options') )
1345                 die('-1');
1346
1347         unset( $_POST['savewidgets'], $_POST['action'] );
1348
1349         // save widgets order for all sidebars
1350         if ( is_array($_POST['sidebars']) ) {
1351                 $sidebars = array();
1352                 foreach ( $_POST['sidebars'] as $key => $val ) {
1353                         $sb = array();
1354                         if ( !empty($val) ) {
1355                                 $val = explode(',', $val);
1356                                 foreach ( $val as $k => $v ) {
1357                                         if ( strpos($v, 'widget-') === false )
1358                                                 continue;
1359
1360                                         $sb[$k] = substr($v, strpos($v, '_') + 1);
1361                                 }
1362                         }
1363                         $sidebars[$key] = $sb;
1364                 }
1365                 wp_set_sidebars_widgets($sidebars);
1366                 die('1');
1367         }
1368
1369         die('-1');
1370         break;
1371 case 'save-widget' :
1372         check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
1373
1374         if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
1375                 die('-1');
1376
1377         unset( $_POST['savewidgets'], $_POST['action'] );
1378
1379         do_action('load-widgets.php');
1380         do_action('widgets.php');
1381         do_action('sidebar_admin_setup');
1382
1383         $id_base = $_POST['id_base'];
1384         $widget_id = $_POST['widget-id'];
1385         $sidebar_id = $_POST['sidebar'];
1386         $multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
1387         $settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
1388         $error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
1389
1390         $sidebars = wp_get_sidebars_widgets();
1391         $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
1392
1393         // delete
1394         if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1395
1396                 if ( !isset($wp_registered_widgets[$widget_id]) )
1397                         die($error);
1398
1399                 $sidebar = array_diff( $sidebar, array($widget_id) );
1400                 $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
1401         } elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
1402                 if ( !$multi_number )
1403                         die($error);
1404
1405                 $_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
1406                 $widget_id = $id_base . '-' . $multi_number;
1407                 $sidebar[] = $widget_id;
1408         }
1409         $_POST['widget-id'] = $sidebar;
1410
1411         foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
1412
1413                 if ( $name == $id_base ) {
1414                         if ( !is_callable( $control['callback'] ) )
1415                                 continue;
1416
1417                         ob_start();
1418                                 call_user_func_array( $control['callback'], $control['params'] );
1419                         ob_end_clean();
1420                         break;
1421                 }
1422         }
1423
1424         if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
1425                 $sidebars[$sidebar_id] = $sidebar;
1426                 wp_set_sidebars_widgets($sidebars);
1427                 echo "deleted:$widget_id";
1428                 die();
1429         }
1430
1431         if ( !empty($_POST['add_new']) )
1432                 die();
1433
1434         if ( $form = $wp_registered_widget_controls[$widget_id] )
1435                 call_user_func_array( $form['callback'], $form['params'] );
1436
1437         die();
1438         break;
1439 case 'image-editor':
1440         $attachment_id = intval($_POST['postid']);
1441         if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
1442                 die('-1');
1443
1444         check_ajax_referer( "image_editor-$attachment_id" );
1445         include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
1446
1447         $msg = false;
1448         switch ( $_POST['do'] ) {
1449                 case 'save' :
1450                         $msg = wp_save_image($attachment_id);
1451                         $msg = json_encode($msg);
1452                         die($msg);
1453                         break;
1454                 case 'scale' :
1455                         $msg = wp_save_image($attachment_id);
1456                         break;
1457                 case 'restore' :
1458                         $msg = wp_restore_image($attachment_id);
1459                         break;
1460         }
1461
1462         wp_image_editor($attachment_id, $msg);
1463         die();
1464         break;
1465 case 'set-post-thumbnail':
1466         $post_ID = intval( $_POST['post_id'] );
1467         if ( !current_user_can( 'edit_post', $post_ID ) )
1468                 die( '-1' );
1469         $thumbnail_id = intval( $_POST['thumbnail_id'] );
1470
1471         check_ajax_referer( "set_post_thumbnail-$post_ID" );
1472
1473         if ( $thumbnail_id == '-1' ) {
1474                 delete_post_meta( $post_ID, '_thumbnail_id' );
1475                 die( _wp_post_thumbnail_html() );
1476         }
1477
1478         if ( set_post_thumbnail( $post_ID, $thumbnail_id ) )
1479                 die( _wp_post_thumbnail_html( $thumbnail_id ) );
1480         die( '0' );
1481         break;
1482 case 'date_format' :
1483         die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
1484         break;
1485 case 'time_format' :
1486         die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
1487         break;
1488 case 'wp-fullscreen-save-post' :
1489         if ( isset($_POST['post_ID']) )
1490                 $post_id = (int) $_POST['post_ID'];
1491         else
1492                 $post_id = 0;
1493
1494         $post = null;
1495         $post_type_object = null;
1496         $post_type = null;
1497         if ( $post_id ) {
1498                 $post = get_post($post_id);
1499                 if ( $post ) {
1500                         $post_type_object = get_post_type_object($post->post_type);
1501                         if ( $post_type_object ) {
1502                                 $post_type = $post->post_type;
1503                                 $current_screen->post_type = $post->post_type;
1504                                 $current_screen->id = $current_screen->post_type;
1505                         }
1506                 }
1507         } elseif ( isset($_POST['post_type']) ) {
1508                 $post_type_object = get_post_type_object($_POST['post_type']);
1509                 if ( $post_type_object ) {
1510                         $post_type = $post_type_object->name;
1511                         $current_screen->post_type = $post_type;
1512                         $current_screen->id = $current_screen->post_type;
1513                 }
1514         }
1515
1516         check_ajax_referer('update-' . $post_type . '_' . $post_id, '_wpnonce');
1517
1518         $post_id = edit_post();
1519
1520         if ( is_wp_error($post_id) ) {
1521                 if ( $post_id->get_error_message() )
1522                         $message = $post_id->get_error_message();
1523                 else
1524                         $message = __('Save failed');
1525
1526                 echo json_encode( array( 'message' => $message, 'last_edited' => '' ) );
1527                 die();
1528         } else {
1529                 $message = __('Saved.');
1530         }
1531
1532         if ( $post ) {
1533                 $last_date = mysql2date( get_option('date_format'), $post->post_modified );
1534                 $last_time = mysql2date( get_option('time_format'), $post->post_modified );
1535         } else {
1536                 $last_date = date_i18n( get_option('date_format') );
1537                 $last_time = date_i18n( get_option('time_format') );
1538         }
1539
1540         if ( $last_id = get_post_meta($post_id, '_edit_last', true) ) {
1541                 $last_user = get_userdata($last_id);
1542                 $last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time );
1543         } else {
1544                 $last_edited = sprintf( __('Last edited on %1$s at %2$s'), $last_date, $last_time );
1545         }
1546
1547         echo json_encode( array( 'message' => $message, 'last_edited' => $last_edited ) );
1548         die();
1549         break;
1550 default :
1551         do_action( 'wp_ajax_' . $_POST['action'] );
1552         die('0');
1553         break;
1554 endswitch;
1555 ?>