PageRenderTime 305ms CodeModel.GetById 74ms app.highlight 211ms RepoModel.GetById 4ms app.codeStats 0ms

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

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