PageRenderTime 572ms CodeModel.GetById 134ms app.highlight 308ms RepoModel.GetById 38ms app.codeStats 1ms

/wp-admin/includes/ajax-actions.php

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