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