wp/wp-admin/includes/ajax-actions.php
changeset 0 d970ebf37754
child 5 5e2f62d02dcd
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     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  */
       
    18 function 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  */
       
    73 function 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 }
       
    90 function 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 
       
   123 function 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 
       
   168 function 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 
       
   182 function 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 
       
   189 function 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 
       
   233 function wp_ajax_dashboard_widgets() {
       
   234 	require_once ABSPATH . 'wp-admin/includes/dashboard.php';
       
   235 
       
   236 	switch ( $_GET['widget'] ) {
       
   237 		case 'dashboard_incoming_links' :
       
   238 			wp_dashboard_incoming_links();
       
   239 			break;
       
   240 		case 'dashboard_primary' :
       
   241 			wp_dashboard_primary();
       
   242 			break;
       
   243 		case 'dashboard_secondary' :
       
   244 			wp_dashboard_secondary();
       
   245 			break;
       
   246 		case 'dashboard_plugins' :
       
   247 			wp_dashboard_plugins();
       
   248 			break;
       
   249 	}
       
   250 	wp_die();
       
   251 }
       
   252 
       
   253 function wp_ajax_logged_in() {
       
   254 	wp_die( 1 );
       
   255 }
       
   256 
       
   257 /*
       
   258  * Ajax helper.
       
   259  */
       
   260 
       
   261 /**
       
   262  * Sends back current comment total and new page links if they need to be updated.
       
   263  *
       
   264  * Contrary to normal success AJAX response ("1"), die with time() on success.
       
   265  *
       
   266  * @since 2.7
       
   267  *
       
   268  * @param int $comment_id
       
   269  * @return die
       
   270  */
       
   271 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
       
   272 	$total    = isset( $_POST['_total'] )    ? (int) $_POST['_total']    : 0;
       
   273 	$per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
       
   274 	$page     = isset( $_POST['_page'] )     ? (int) $_POST['_page']     : 0;
       
   275 	$url      = isset( $_POST['_url'] )      ? esc_url_raw( $_POST['_url'] ) : '';
       
   276 
       
   277 	// JS didn't send us everything we need to know. Just die with success message
       
   278 	if ( !$total || !$per_page || !$page || !$url )
       
   279 		wp_die( time() );
       
   280 
       
   281 	$total += $delta;
       
   282 	if ( $total < 0 )
       
   283 		$total = 0;
       
   284 
       
   285 	// Only do the expensive stuff on a page-break, and about 1 other time per page
       
   286 	if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
       
   287 		$post_id = 0;
       
   288 		$status = 'total_comments'; // What type of comment count are we looking for?
       
   289 		$parsed = parse_url( $url );
       
   290 		if ( isset( $parsed['query'] ) ) {
       
   291 			parse_str( $parsed['query'], $query_vars );
       
   292 			if ( !empty( $query_vars['comment_status'] ) )
       
   293 				$status = $query_vars['comment_status'];
       
   294 			if ( !empty( $query_vars['p'] ) )
       
   295 				$post_id = (int) $query_vars['p'];
       
   296 		}
       
   297 
       
   298 		$comment_count = wp_count_comments($post_id);
       
   299 
       
   300 		if ( isset( $comment_count->$status ) ) // We're looking for a known type of comment count
       
   301 			$total = $comment_count->$status;
       
   302 			// else use the decremented value from above
       
   303 	}
       
   304 
       
   305 	$time = time(); // The time since the last comment count
       
   306 
       
   307 	$x = new WP_Ajax_Response( array(
       
   308 		'what' => 'comment',
       
   309 		'id' => $comment_id, // here for completeness - not used
       
   310 		'supplemental' => array(
       
   311 			'total_items_i18n' => sprintf( _n( '1 item', '%s items', $total ), number_format_i18n( $total ) ),
       
   312 			'total_pages' => ceil( $total / $per_page ),
       
   313 			'total_pages_i18n' => number_format_i18n( ceil( $total / $per_page ) ),
       
   314 			'total' => $total,
       
   315 			'time' => $time
       
   316 		)
       
   317 	) );
       
   318 	$x->send();
       
   319 }
       
   320 
       
   321 /*
       
   322  * POST-based Ajax handlers.
       
   323  */
       
   324 
       
   325 function _wp_ajax_add_hierarchical_term() {
       
   326 	$action = $_POST['action'];
       
   327 	$taxonomy = get_taxonomy(substr($action, 4));
       
   328 	check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
       
   329 	if ( !current_user_can( $taxonomy->cap->edit_terms ) )
       
   330 		wp_die( -1 );
       
   331 	$names = explode(',', $_POST['new'.$taxonomy->name]);
       
   332 	$parent = isset($_POST['new'.$taxonomy->name.'_parent']) ? (int) $_POST['new'.$taxonomy->name.'_parent'] : 0;
       
   333 	if ( 0 > $parent )
       
   334 		$parent = 0;
       
   335 	if ( $taxonomy->name == 'category' )
       
   336 		$post_category = isset($_POST['post_category']) ? (array) $_POST['post_category'] : array();
       
   337 	else
       
   338 		$post_category = ( isset($_POST['tax_input']) && isset($_POST['tax_input'][$taxonomy->name]) ) ? (array) $_POST['tax_input'][$taxonomy->name] : array();
       
   339 	$checked_categories = array_map( 'absint', (array) $post_category );
       
   340 	$popular_ids = wp_popular_terms_checklist($taxonomy->name, 0, 10, false);
       
   341 
       
   342 	foreach ( $names as $cat_name ) {
       
   343 		$cat_name = trim($cat_name);
       
   344 		$category_nicename = sanitize_title($cat_name);
       
   345 		if ( '' === $category_nicename )
       
   346 			continue;
       
   347 		if ( !$cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) )
       
   348 			$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
       
   349 		if ( is_wp_error( $cat_id ) )
       
   350 			continue;
       
   351 		else if ( is_array( $cat_id ) )
       
   352 			$cat_id = $cat_id['term_id'];
       
   353 		$checked_categories[] = $cat_id;
       
   354 		if ( $parent ) // Do these all at once in a second
       
   355 			continue;
       
   356 		ob_start();
       
   357 			wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name, 'descendants_and_self' => $cat_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids ));
       
   358 		$data = ob_get_contents();
       
   359 		ob_end_clean();
       
   360 		$add = array(
       
   361 			'what' => $taxonomy->name,
       
   362 			'id' => $cat_id,
       
   363 			'data' => str_replace( array("\n", "\t"), '', $data),
       
   364 			'position' => -1
       
   365 		);
       
   366 	}
       
   367 
       
   368 	if ( $parent ) { // Foncy - replace the parent and all its children
       
   369 		$parent = get_term( $parent, $taxonomy->name );
       
   370 		$term_id = $parent->term_id;
       
   371 
       
   372 		while ( $parent->parent ) { // get the top parent
       
   373 			$parent = get_term( $parent->parent, $taxonomy->name );
       
   374 			if ( is_wp_error( $parent ) )
       
   375 				break;
       
   376 			$term_id = $parent->term_id;
       
   377 		}
       
   378 
       
   379 		ob_start();
       
   380 			wp_terms_checklist( 0, array('taxonomy' => $taxonomy->name, 'descendants_and_self' => $term_id, 'selected_cats' => $checked_categories, 'popular_cats' => $popular_ids));
       
   381 		$data = ob_get_contents();
       
   382 		ob_end_clean();
       
   383 		$add = array(
       
   384 			'what' => $taxonomy->name,
       
   385 			'id' => $term_id,
       
   386 			'data' => str_replace( array("\n", "\t"), '', $data),
       
   387 			'position' => -1
       
   388 		);
       
   389 	}
       
   390 
       
   391 	ob_start();
       
   392 		wp_dropdown_categories( array(
       
   393 			'taxonomy' => $taxonomy->name, 'hide_empty' => 0, 'name' => 'new'.$taxonomy->name.'_parent', 'orderby' => 'name',
       
   394 			'hierarchical' => 1, 'show_option_none' => '&mdash; '.$taxonomy->labels->parent_item.' &mdash;'
       
   395 		) );
       
   396 	$sup = ob_get_contents();
       
   397 	ob_end_clean();
       
   398 	$add['supplemental'] = array( 'newcat_parent' => $sup );
       
   399 
       
   400 	$x = new WP_Ajax_Response( $add );
       
   401 	$x->send();
       
   402 }
       
   403 
       
   404 function wp_ajax_delete_comment() {
       
   405 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   406 
       
   407 	if ( !$comment = get_comment( $id ) )
       
   408 		wp_die( time() );
       
   409 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
       
   410 		wp_die( -1 );
       
   411 
       
   412 	check_ajax_referer( "delete-comment_$id" );
       
   413 	$status = wp_get_comment_status( $comment->comment_ID );
       
   414 
       
   415 	$delta = -1;
       
   416 	if ( isset($_POST['trash']) && 1 == $_POST['trash'] ) {
       
   417 		if ( 'trash' == $status )
       
   418 			wp_die( time() );
       
   419 		$r = wp_trash_comment( $comment->comment_ID );
       
   420 	} elseif ( isset($_POST['untrash']) && 1 == $_POST['untrash'] ) {
       
   421 		if ( 'trash' != $status )
       
   422 			wp_die( time() );
       
   423 		$r = wp_untrash_comment( $comment->comment_ID );
       
   424 		if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) // undo trash, not in trash
       
   425 			$delta = 1;
       
   426 	} elseif ( isset($_POST['spam']) && 1 == $_POST['spam'] ) {
       
   427 		if ( 'spam' == $status )
       
   428 			wp_die( time() );
       
   429 		$r = wp_spam_comment( $comment->comment_ID );
       
   430 	} elseif ( isset($_POST['unspam']) && 1 == $_POST['unspam'] ) {
       
   431 		if ( 'spam' != $status )
       
   432 			wp_die( time() );
       
   433 		$r = wp_unspam_comment( $comment->comment_ID );
       
   434 		if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) // undo spam, not in spam
       
   435 			$delta = 1;
       
   436 	} elseif ( isset($_POST['delete']) && 1 == $_POST['delete'] ) {
       
   437 		$r = wp_delete_comment( $comment->comment_ID );
       
   438 	} else {
       
   439 		wp_die( -1 );
       
   440 	}
       
   441 
       
   442 	if ( $r ) // Decide if we need to send back '1' or a more complicated response including page links and comment counts
       
   443 		_wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
       
   444 	wp_die( 0 );
       
   445 }
       
   446 
       
   447 function wp_ajax_delete_tag() {
       
   448 	$tag_id = (int) $_POST['tag_ID'];
       
   449 	check_ajax_referer( "delete-tag_$tag_id" );
       
   450 
       
   451 	$taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
       
   452 	$tax = get_taxonomy($taxonomy);
       
   453 
       
   454 	if ( !current_user_can( $tax->cap->delete_terms ) )
       
   455 		wp_die( -1 );
       
   456 
       
   457 	$tag = get_term( $tag_id, $taxonomy );
       
   458 	if ( !$tag || is_wp_error( $tag ) )
       
   459 		wp_die( 1 );
       
   460 
       
   461 	if ( wp_delete_term($tag_id, $taxonomy))
       
   462 		wp_die( 1 );
       
   463 	else
       
   464 		wp_die( 0 );
       
   465 }
       
   466 
       
   467 function wp_ajax_delete_link() {
       
   468 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   469 
       
   470 	check_ajax_referer( "delete-bookmark_$id" );
       
   471 	if ( !current_user_can( 'manage_links' ) )
       
   472 		wp_die( -1 );
       
   473 
       
   474 	$link = get_bookmark( $id );
       
   475 	if ( !$link || is_wp_error( $link ) )
       
   476 		wp_die( 1 );
       
   477 
       
   478 	if ( wp_delete_link( $id ) )
       
   479 		wp_die( 1 );
       
   480 	else
       
   481 		wp_die( 0 );
       
   482 }
       
   483 
       
   484 function wp_ajax_delete_meta() {
       
   485 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   486 
       
   487 	check_ajax_referer( "delete-meta_$id" );
       
   488 	if ( !$meta = get_metadata_by_mid( 'post', $id ) )
       
   489 		wp_die( 1 );
       
   490 
       
   491 	if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta',  $meta->post_id, $meta->meta_key ) )
       
   492 		wp_die( -1 );
       
   493 	if ( delete_meta( $meta->meta_id ) )
       
   494 		wp_die( 1 );
       
   495 	wp_die( 0 );
       
   496 }
       
   497 
       
   498 function wp_ajax_delete_post( $action ) {
       
   499 	if ( empty( $action ) )
       
   500 		$action = 'delete-post';
       
   501 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   502 
       
   503 	check_ajax_referer( "{$action}_$id" );
       
   504 	if ( !current_user_can( 'delete_post', $id ) )
       
   505 		wp_die( -1 );
       
   506 
       
   507 	if ( !get_post( $id ) )
       
   508 		wp_die( 1 );
       
   509 
       
   510 	if ( wp_delete_post( $id ) )
       
   511 		wp_die( 1 );
       
   512 	else
       
   513 		wp_die( 0 );
       
   514 }
       
   515 
       
   516 function wp_ajax_trash_post( $action ) {
       
   517 	if ( empty( $action ) )
       
   518 		$action = 'trash-post';
       
   519 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   520 
       
   521 	check_ajax_referer( "{$action}_$id" );
       
   522 	if ( !current_user_can( 'delete_post', $id ) )
       
   523 		wp_die( -1 );
       
   524 
       
   525 	if ( !get_post( $id ) )
       
   526 		wp_die( 1 );
       
   527 
       
   528 	if ( 'trash-post' == $action )
       
   529 		$done = wp_trash_post( $id );
       
   530 	else
       
   531 		$done = wp_untrash_post( $id );
       
   532 
       
   533 	if ( $done )
       
   534 		wp_die( 1 );
       
   535 
       
   536 	wp_die( 0 );
       
   537 }
       
   538 
       
   539 function wp_ajax_untrash_post( $action ) {
       
   540 	if ( empty( $action ) )
       
   541 		$action = 'untrash-post';
       
   542 	wp_ajax_trash_post( $action );
       
   543 }
       
   544 
       
   545 function wp_ajax_delete_page( $action ) {
       
   546 	if ( empty( $action ) )
       
   547 		$action = 'delete-page';
       
   548 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   549 
       
   550 	check_ajax_referer( "{$action}_$id" );
       
   551 	if ( !current_user_can( 'delete_page', $id ) )
       
   552 		wp_die( -1 );
       
   553 
       
   554 	if ( ! get_post( $id ) )
       
   555 		wp_die( 1 );
       
   556 
       
   557 	if ( wp_delete_post( $id ) )
       
   558 		wp_die( 1 );
       
   559 	else
       
   560 		wp_die( 0 );
       
   561 }
       
   562 
       
   563 function wp_ajax_dim_comment() {
       
   564 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
       
   565 
       
   566 	if ( !$comment = get_comment( $id ) ) {
       
   567 		$x = new WP_Ajax_Response( array(
       
   568 			'what' => 'comment',
       
   569 			'id' => new WP_Error('invalid_comment', sprintf(__('Comment %d does not exist'), $id))
       
   570 		) );
       
   571 		$x->send();
       
   572 	}
       
   573 
       
   574 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) )
       
   575 		wp_die( -1 );
       
   576 
       
   577 	$current = wp_get_comment_status( $comment->comment_ID );
       
   578 	if ( isset( $_POST['new'] ) && $_POST['new'] == $current )
       
   579 		wp_die( time() );
       
   580 
       
   581 	check_ajax_referer( "approve-comment_$id" );
       
   582 	if ( in_array( $current, array( 'unapproved', 'spam' ) ) )
       
   583 		$result = wp_set_comment_status( $comment->comment_ID, 'approve', true );
       
   584 	else
       
   585 		$result = wp_set_comment_status( $comment->comment_ID, 'hold', true );
       
   586 
       
   587 	if ( is_wp_error($result) ) {
       
   588 		$x = new WP_Ajax_Response( array(
       
   589 			'what' => 'comment',
       
   590 			'id' => $result
       
   591 		) );
       
   592 		$x->send();
       
   593 	}
       
   594 
       
   595 	// Decide if we need to send back '1' or a more complicated response including page links and comment counts
       
   596 	_wp_ajax_delete_comment_response( $comment->comment_ID );
       
   597 	wp_die( 0 );
       
   598 }
       
   599 
       
   600 function wp_ajax_add_link_category( $action ) {
       
   601 	if ( empty( $action ) )
       
   602 		$action = 'add-link-category';
       
   603 	check_ajax_referer( $action );
       
   604 	if ( !current_user_can( 'manage_categories' ) )
       
   605 		wp_die( -1 );
       
   606 	$names = explode(',', wp_unslash( $_POST['newcat'] ) );
       
   607 	$x = new WP_Ajax_Response();
       
   608 	foreach ( $names as $cat_name ) {
       
   609 		$cat_name = trim($cat_name);
       
   610 		$slug = sanitize_title($cat_name);
       
   611 		if ( '' === $slug )
       
   612 			continue;
       
   613 		if ( !$cat_id = term_exists( $cat_name, 'link_category' ) )
       
   614 			$cat_id = wp_insert_term( $cat_name, 'link_category' );
       
   615 		if ( is_wp_error( $cat_id ) )
       
   616 			continue;
       
   617 		else if ( is_array( $cat_id ) )
       
   618 			$cat_id = $cat_id['term_id'];
       
   619 		$cat_name = esc_html( $cat_name );
       
   620 		$x->add( array(
       
   621 			'what' => 'link-category',
       
   622 			'id' => $cat_id,
       
   623 			'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>",
       
   624 			'position' => -1
       
   625 		) );
       
   626 	}
       
   627 	$x->send();
       
   628 }
       
   629 
       
   630 function wp_ajax_add_tag() {
       
   631 	global $wp_list_table;
       
   632 
       
   633 	check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
       
   634 	$post_type = !empty($_POST['post_type']) ? $_POST['post_type'] : 'post';
       
   635 	$taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
       
   636 	$tax = get_taxonomy($taxonomy);
       
   637 
       
   638 	if ( !current_user_can( $tax->cap->edit_terms ) )
       
   639 		wp_die( -1 );
       
   640 
       
   641 	$x = new WP_Ajax_Response();
       
   642 
       
   643 	$tag = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST );
       
   644 
       
   645 	if ( !$tag || is_wp_error($tag) || (!$tag = get_term( $tag['term_id'], $taxonomy )) ) {
       
   646 		$message = __('An error has occurred. Please reload the page and try again.');
       
   647 		if ( is_wp_error($tag) && $tag->get_error_message() )
       
   648 			$message = $tag->get_error_message();
       
   649 
       
   650 		$x->add( array(
       
   651 			'what' => 'taxonomy',
       
   652 			'data' => new WP_Error('error', $message )
       
   653 		) );
       
   654 		$x->send();
       
   655 	}
       
   656 
       
   657 	$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => $_POST['screen'] ) );
       
   658 
       
   659 	$level = 0;
       
   660 	if ( is_taxonomy_hierarchical($taxonomy) ) {
       
   661 		$level = count( get_ancestors( $tag->term_id, $taxonomy ) );
       
   662 		ob_start();
       
   663 		$wp_list_table->single_row( $tag, $level );
       
   664 		$noparents = ob_get_clean();
       
   665 	}
       
   666 
       
   667 	ob_start();
       
   668 	$wp_list_table->single_row( $tag );
       
   669 	$parents = ob_get_clean();
       
   670 
       
   671 	$x->add( array(
       
   672 		'what' => 'taxonomy',
       
   673 		'supplemental' => compact('parents', 'noparents')
       
   674 		) );
       
   675 	$x->add( array(
       
   676 		'what' => 'term',
       
   677 		'position' => $level,
       
   678 		'supplemental' => (array) $tag
       
   679 		) );
       
   680 	$x->send();
       
   681 }
       
   682 
       
   683 function wp_ajax_get_tagcloud() {
       
   684 	if ( isset( $_POST['tax'] ) ) {
       
   685 		$taxonomy = sanitize_key( $_POST['tax'] );
       
   686 		$tax = get_taxonomy( $taxonomy );
       
   687 		if ( ! $tax )
       
   688 			wp_die( 0 );
       
   689 		if ( ! current_user_can( $tax->cap->assign_terms ) )
       
   690 			wp_die( -1 );
       
   691 	} else {
       
   692 		wp_die( 0 );
       
   693 	}
       
   694 
       
   695 	$tags = get_terms( $taxonomy, array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
       
   696 
       
   697 	if ( empty( $tags ) )
       
   698 		wp_die( $tax->labels->not_found );
       
   699 
       
   700 	if ( is_wp_error( $tags ) )
       
   701 		wp_die( $tags->get_error_message() );
       
   702 
       
   703 	foreach ( $tags as $key => $tag ) {
       
   704 		$tags[ $key ]->link = '#';
       
   705 		$tags[ $key ]->id = $tag->term_id;
       
   706 	}
       
   707 
       
   708 	// We need raw tag names here, so don't filter the output
       
   709 	$return = wp_generate_tag_cloud( $tags, array('filter' => 0) );
       
   710 
       
   711 	if ( empty($return) )
       
   712 		wp_die( 0 );
       
   713 
       
   714 	echo $return;
       
   715 
       
   716 	wp_die();
       
   717 }
       
   718 
       
   719 function wp_ajax_get_comments( $action ) {
       
   720 	global $wp_list_table, $post_id;
       
   721 	if ( empty( $action ) )
       
   722 		$action = 'get-comments';
       
   723 
       
   724 	check_ajax_referer( $action );
       
   725 
       
   726 	if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) {
       
   727 		$id = absint( $_REQUEST['p'] );
       
   728 		if ( ! empty( $id ) )
       
   729 			$post_id = $id;
       
   730 	}
       
   731 
       
   732 	if ( empty( $post_id ) )
       
   733 		wp_die( -1 );
       
   734 
       
   735 	$wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
       
   736 
       
   737 	if ( ! current_user_can( 'edit_post', $post_id ) )
       
   738 		wp_die( -1 );
       
   739 
       
   740 	$wp_list_table->prepare_items();
       
   741 
       
   742 	if ( !$wp_list_table->has_items() )
       
   743 		wp_die( 1 );
       
   744 
       
   745 	$x = new WP_Ajax_Response();
       
   746 	ob_start();
       
   747 	foreach ( $wp_list_table->items as $comment ) {
       
   748 		if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) )
       
   749 			continue;
       
   750 		get_comment( $comment );
       
   751 		$wp_list_table->single_row( $comment );
       
   752 	}
       
   753 	$comment_list_item = ob_get_contents();
       
   754 	ob_end_clean();
       
   755 
       
   756 	$x->add( array(
       
   757 		'what' => 'comments',
       
   758 		'data' => $comment_list_item
       
   759 	) );
       
   760 	$x->send();
       
   761 }
       
   762 
       
   763 function wp_ajax_replyto_comment( $action ) {
       
   764 	global $wp_list_table, $wpdb;
       
   765 	if ( empty( $action ) )
       
   766 		$action = 'replyto-comment';
       
   767 
       
   768 	check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
       
   769 
       
   770 	$comment_post_ID = (int) $_POST['comment_post_ID'];
       
   771 	$post = get_post( $comment_post_ID );
       
   772 	if ( ! $post )
       
   773 		wp_die( -1 );
       
   774 
       
   775 	if ( !current_user_can( 'edit_post', $comment_post_ID ) )
       
   776 		wp_die( -1 );
       
   777 
       
   778 	if ( empty( $post->post_status ) )
       
   779 		wp_die( 1 );
       
   780 	elseif ( in_array($post->post_status, array('draft', 'pending', 'trash') ) )
       
   781 		wp_die( __('ERROR: you are replying to a comment on a draft post.') );
       
   782 
       
   783 	$user = wp_get_current_user();
       
   784 	if ( $user->exists() ) {
       
   785 		$user_ID = $user->ID;
       
   786 		$comment_author       = wp_slash( $user->display_name );
       
   787 		$comment_author_email = wp_slash( $user->user_email );
       
   788 		$comment_author_url   = wp_slash( $user->user_url );
       
   789 		$comment_content      = trim($_POST['content']);
       
   790 		if ( current_user_can( 'unfiltered_html' ) ) {
       
   791 			if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) )
       
   792 				$_POST['_wp_unfiltered_html_comment'] = '';
       
   793 
       
   794 			if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
       
   795 				kses_remove_filters(); // start with a clean slate
       
   796 				kses_init_filters(); // set up the filters
       
   797 			}
       
   798 		}
       
   799 	} else {
       
   800 		wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
       
   801 	}
       
   802 
       
   803 	if ( '' == $comment_content )
       
   804 		wp_die( __( 'ERROR: please type a comment.' ) );
       
   805 
       
   806 	$comment_parent = 0;
       
   807 	if ( isset( $_POST['comment_ID'] ) )
       
   808 		$comment_parent = absint( $_POST['comment_ID'] );
       
   809 	$comment_auto_approved = false;
       
   810 	$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
       
   811 
       
   812 	// automatically approve parent comment
       
   813 	if ( !empty($_POST['approve_parent']) ) {
       
   814 		$parent = get_comment( $comment_parent );
       
   815 
       
   816 		if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
       
   817 			if ( wp_set_comment_status( $parent->comment_ID, 'approve' ) )
       
   818 				$comment_auto_approved = true;
       
   819 		}
       
   820 	}
       
   821 
       
   822 	$comment_id = wp_new_comment( $commentdata );
       
   823 	$comment = get_comment($comment_id);
       
   824 	if ( ! $comment ) wp_die( 1 );
       
   825 
       
   826 	$position = ( isset($_POST['position']) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
       
   827 
       
   828 	ob_start();
       
   829 	if ( isset( $_REQUEST['mode'] ) && 'dashboard' == $_REQUEST['mode'] ) {
       
   830 		require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
       
   831 		_wp_dashboard_recent_comments_row( $comment );
       
   832 	} else {
       
   833 		if ( isset( $_REQUEST['mode'] ) && 'single' == $_REQUEST['mode'] ) {
       
   834 			$wp_list_table = _get_list_table('WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
       
   835 		} else {
       
   836 			$wp_list_table = _get_list_table('WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
       
   837 		}
       
   838 		$wp_list_table->single_row( $comment );
       
   839 	}
       
   840 	$comment_list_item = ob_get_clean();
       
   841 
       
   842 	$response =  array(
       
   843 		'what' => 'comment',
       
   844 		'id' => $comment->comment_ID,
       
   845 		'data' => $comment_list_item,
       
   846 		'position' => $position
       
   847 	);
       
   848 
       
   849 	if ( $comment_auto_approved )
       
   850 		$response['supplemental'] = array( 'parent_approved' => $parent->comment_ID );
       
   851 
       
   852 	$x = new WP_Ajax_Response();
       
   853 	$x->add( $response );
       
   854 	$x->send();
       
   855 }
       
   856 
       
   857 function wp_ajax_edit_comment() {
       
   858 	global $wp_list_table;
       
   859 
       
   860 	check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
       
   861 
       
   862 	$comment_id = (int) $_POST['comment_ID'];
       
   863 	if ( ! current_user_can( 'edit_comment', $comment_id ) )
       
   864 		wp_die( -1 );
       
   865 
       
   866 	if ( '' == $_POST['content'] )
       
   867 		wp_die( __( 'ERROR: please type a comment.' ) );
       
   868 
       
   869 	if ( isset( $_POST['status'] ) )
       
   870 		$_POST['comment_status'] = $_POST['status'];
       
   871 	edit_comment();
       
   872 
       
   873 	$position = ( isset($_POST['position']) && (int) $_POST['position']) ? (int) $_POST['position'] : '-1';
       
   874 	$comments_status = isset($_POST['comments_listing']) ? $_POST['comments_listing'] : '';
       
   875 
       
   876 	$checkbox = ( isset($_POST['checkbox']) && true == $_POST['checkbox'] ) ? 1 : 0;
       
   877 	$wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
       
   878 
       
   879 	$comment = get_comment( $comment_id );
       
   880 	if ( empty( $comment->comment_ID ) )
       
   881 		wp_die( -1 );
       
   882 
       
   883 	ob_start();
       
   884 	$wp_list_table->single_row( $comment );
       
   885 	$comment_list_item = ob_get_clean();
       
   886 
       
   887 	$x = new WP_Ajax_Response();
       
   888 
       
   889 	$x->add( array(
       
   890 		'what' => 'edit_comment',
       
   891 		'id' => $comment->comment_ID,
       
   892 		'data' => $comment_list_item,
       
   893 		'position' => $position
       
   894 	));
       
   895 
       
   896 	$x->send();
       
   897 }
       
   898 
       
   899 function wp_ajax_add_menu_item() {
       
   900 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
       
   901 
       
   902 	if ( ! current_user_can( 'edit_theme_options' ) )
       
   903 		wp_die( -1 );
       
   904 
       
   905 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
       
   906 
       
   907 	// For performance reasons, we omit some object properties from the checklist.
       
   908 	// The following is a hacky way to restore them when adding non-custom items.
       
   909 
       
   910 	$menu_items_data = array();
       
   911 	foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
       
   912 		if (
       
   913 			! empty( $menu_item_data['menu-item-type'] ) &&
       
   914 			'custom' != $menu_item_data['menu-item-type'] &&
       
   915 			! empty( $menu_item_data['menu-item-object-id'] )
       
   916 		) {
       
   917 			switch( $menu_item_data['menu-item-type'] ) {
       
   918 				case 'post_type' :
       
   919 					$_object = get_post( $menu_item_data['menu-item-object-id'] );
       
   920 				break;
       
   921 
       
   922 				case 'taxonomy' :
       
   923 					$_object = get_term( $menu_item_data['menu-item-object-id'], $menu_item_data['menu-item-object'] );
       
   924 				break;
       
   925 			}
       
   926 
       
   927 			$_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
       
   928 			$_menu_item = array_shift( $_menu_items );
       
   929 
       
   930 			// Restore the missing menu item properties
       
   931 			$menu_item_data['menu-item-description'] = $_menu_item->description;
       
   932 		}
       
   933 
       
   934 		$menu_items_data[] = $menu_item_data;
       
   935 	}
       
   936 
       
   937 	$item_ids = wp_save_nav_menu_items( 0, $menu_items_data );
       
   938 	if ( is_wp_error( $item_ids ) )
       
   939 		wp_die( 0 );
       
   940 
       
   941 	$menu_items = array();
       
   942 
       
   943 	foreach ( (array) $item_ids as $menu_item_id ) {
       
   944 		$menu_obj = get_post( $menu_item_id );
       
   945 		if ( ! empty( $menu_obj->ID ) ) {
       
   946 			$menu_obj = wp_setup_nav_menu_item( $menu_obj );
       
   947 			$menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
       
   948 			$menu_items[] = $menu_obj;
       
   949 		}
       
   950 	}
       
   951 
       
   952 	/**
       
   953 	 * Filter the Walker class used when adding nav menu items.
       
   954 	 *
       
   955 	 * @since 3.4.0
       
   956 	 *
       
   957 	 * @param string $class   The walker class to use. Default 'Walker_Nav_Menu_Edit'.
       
   958 	 * @param int    $menu_id The menu id, derived from $_POST['menu'].
       
   959 	 */
       
   960 	$walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $_POST['menu'] );
       
   961 
       
   962 	if ( ! class_exists( $walker_class_name ) )
       
   963 		wp_die( 0 );
       
   964 
       
   965 	if ( ! empty( $menu_items ) ) {
       
   966 		$args = array(
       
   967 			'after' => '',
       
   968 			'before' => '',
       
   969 			'link_after' => '',
       
   970 			'link_before' => '',
       
   971 			'walker' => new $walker_class_name,
       
   972 		);
       
   973 		echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
       
   974 	}
       
   975 	wp_die();
       
   976 }
       
   977 
       
   978 function wp_ajax_add_meta() {
       
   979 	check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
       
   980 	$c = 0;
       
   981 	$pid = (int) $_POST['post_id'];
       
   982 	$post = get_post( $pid );
       
   983 
       
   984 	if ( isset($_POST['metakeyselect']) || isset($_POST['metakeyinput']) ) {
       
   985 		if ( !current_user_can( 'edit_post', $pid ) )
       
   986 			wp_die( -1 );
       
   987 		if ( isset($_POST['metakeyselect']) && '#NONE#' == $_POST['metakeyselect'] && empty($_POST['metakeyinput']) )
       
   988 			wp_die( 1 );
       
   989 		if ( $post->post_status == 'auto-draft' ) {
       
   990 			$save_POST = $_POST; // Backup $_POST
       
   991 			$_POST = array(); // Make it empty for edit_post()
       
   992 			$_POST['action'] = 'draft'; // Warning fix
       
   993 			$_POST['post_ID'] = $pid;
       
   994 			$_POST['post_type'] = $post->post_type;
       
   995 			$_POST['post_status'] = 'draft';
       
   996 			$now = current_time('timestamp', 1);
       
   997 			$_POST['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( get_option( 'date_format' ), $now ), date( get_option( 'time_format' ), $now ) );
       
   998 
       
   999 			if ( $pid = edit_post() ) {
       
  1000 				if ( is_wp_error( $pid ) ) {
       
  1001 					$x = new WP_Ajax_Response( array(
       
  1002 						'what' => 'meta',
       
  1003 						'data' => $pid
       
  1004 					) );
       
  1005 					$x->send();
       
  1006 				}
       
  1007 				$_POST = $save_POST; // Now we can restore original $_POST again
       
  1008 				if ( !$mid = add_meta( $pid ) )
       
  1009 					wp_die( __( 'Please provide a custom field value.' ) );
       
  1010 			} else {
       
  1011 				wp_die( 0 );
       
  1012 			}
       
  1013 		} else if ( !$mid = add_meta( $pid ) ) {
       
  1014 			wp_die( __( 'Please provide a custom field value.' ) );
       
  1015 		}
       
  1016 
       
  1017 		$meta = get_metadata_by_mid( 'post', $mid );
       
  1018 		$pid = (int) $meta->post_id;
       
  1019 		$meta = get_object_vars( $meta );
       
  1020 		$x = new WP_Ajax_Response( array(
       
  1021 			'what' => 'meta',
       
  1022 			'id' => $mid,
       
  1023 			'data' => _list_meta_row( $meta, $c ),
       
  1024 			'position' => 1,
       
  1025 			'supplemental' => array('postid' => $pid)
       
  1026 		) );
       
  1027 	} else { // Update?
       
  1028 		$mid = (int) key( $_POST['meta'] );
       
  1029 		$key = wp_unslash( $_POST['meta'][$mid]['key'] );
       
  1030 		$value = wp_unslash( $_POST['meta'][$mid]['value'] );
       
  1031 		if ( '' == trim($key) )
       
  1032 			wp_die( __( 'Please provide a custom field name.' ) );
       
  1033 		if ( '' == trim($value) )
       
  1034 			wp_die( __( 'Please provide a custom field value.' ) );
       
  1035 		if ( ! $meta = get_metadata_by_mid( 'post', $mid ) )
       
  1036 			wp_die( 0 ); // if meta doesn't exist
       
  1037 		if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
       
  1038 			! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
       
  1039 			! current_user_can( 'edit_post_meta', $meta->post_id, $key ) )
       
  1040 			wp_die( -1 );
       
  1041 		if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
       
  1042 			if ( !$u = update_metadata_by_mid( 'post', $mid, $value, $key ) )
       
  1043 				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
       
  1044 		}
       
  1045 
       
  1046 		$x = new WP_Ajax_Response( array(
       
  1047 			'what' => 'meta',
       
  1048 			'id' => $mid, 'old_id' => $mid,
       
  1049 			'data' => _list_meta_row( array(
       
  1050 				'meta_key' => $key,
       
  1051 				'meta_value' => $value,
       
  1052 				'meta_id' => $mid
       
  1053 			), $c ),
       
  1054 			'position' => 0,
       
  1055 			'supplemental' => array('postid' => $meta->post_id)
       
  1056 		) );
       
  1057 	}
       
  1058 	$x->send();
       
  1059 }
       
  1060 
       
  1061 function wp_ajax_add_user( $action ) {
       
  1062 	global $wp_list_table;
       
  1063 	if ( empty( $action ) )
       
  1064 		$action = 'add-user';
       
  1065 
       
  1066 	check_ajax_referer( $action );
       
  1067 	if ( ! current_user_can('create_users') )
       
  1068 		wp_die( -1 );
       
  1069 	if ( ! $user_id = edit_user() ) {
       
  1070 		wp_die( 0 );
       
  1071 	} elseif ( is_wp_error( $user_id ) ) {
       
  1072 		$x = new WP_Ajax_Response( array(
       
  1073 			'what' => 'user',
       
  1074 			'id' => $user_id
       
  1075 		) );
       
  1076 		$x->send();
       
  1077 	}
       
  1078 	$user_object = get_userdata( $user_id );
       
  1079 
       
  1080 	$wp_list_table = _get_list_table('WP_Users_List_Table');
       
  1081 
       
  1082 	$role = current( $user_object->roles );
       
  1083 
       
  1084 	$x = new WP_Ajax_Response( array(
       
  1085 		'what' => 'user',
       
  1086 		'id' => $user_id,
       
  1087 		'data' => $wp_list_table->single_row( $user_object, '', $role ),
       
  1088 		'supplemental' => array(
       
  1089 			'show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login),
       
  1090 			'role' => $role,
       
  1091 		)
       
  1092 	) );
       
  1093 	$x->send();
       
  1094 }
       
  1095 
       
  1096 function wp_ajax_autosave() {
       
  1097 	define( 'DOING_AUTOSAVE', true );
       
  1098 
       
  1099 	check_ajax_referer( 'autosave', 'autosavenonce' );
       
  1100 
       
  1101 	if ( ! empty( $_POST['catslist'] ) )
       
  1102 		$_POST['post_category'] = explode( ',', $_POST['catslist'] );
       
  1103 	if ( $_POST['post_type'] == 'page' || empty( $_POST['post_category'] ) )
       
  1104 		unset( $_POST['post_category'] );
       
  1105 
       
  1106 	$data = '';
       
  1107 	$supplemental = array();
       
  1108 	$id = $revision_id = 0;
       
  1109 
       
  1110 	$post_id = (int) $_POST['post_id'];
       
  1111 	$_POST['ID'] = $_POST['post_ID'] = $post_id;
       
  1112 	$post = get_post( $post_id );
       
  1113 	if ( empty( $post->ID ) || ! current_user_can( 'edit_post', $post->ID ) )
       
  1114 		wp_die( __( 'You are not allowed to edit this post.' ) );
       
  1115 
       
  1116 	if ( 'page' == $post->post_type && ! current_user_can( 'edit_page', $post->ID ) )
       
  1117 		wp_die( __( 'You are not allowed to edit this page.' ) );
       
  1118 
       
  1119 	if ( 'auto-draft' == $post->post_status )
       
  1120 		$_POST['post_status'] = 'draft';
       
  1121 
       
  1122 	if ( ! empty( $_POST['autosave'] ) ) {
       
  1123 		if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author && ( 'auto-draft' == $post->post_status || 'draft' == $post->post_status ) ) {
       
  1124 			// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked
       
  1125 			$id = edit_post();
       
  1126 		} else {
       
  1127 			// Non drafts or other users drafts are not overwritten. The autosave is stored in a special post revision for each user.
       
  1128 			$revision_id = wp_create_post_autosave( $post->ID );
       
  1129 			if ( is_wp_error($revision_id) )
       
  1130 				$id = $revision_id;
       
  1131 			else
       
  1132 				$id = $post->ID;
       
  1133 		}
       
  1134 
       
  1135 		if ( ! is_wp_error($id) ) {
       
  1136 			/* translators: draft saved date format, see http://php.net/date */
       
  1137 			$draft_saved_date_format = __('g:i:s a');
       
  1138 			/* translators: %s: date and time */
       
  1139 			$data = sprintf( __('Draft saved at %s.'), date_i18n( $draft_saved_date_format ) );
       
  1140 		}
       
  1141 	} else {
       
  1142 		if ( ! empty( $_POST['auto_draft'] ) )
       
  1143 			$id = 0; // This tells us it didn't actually save
       
  1144 		else
       
  1145 			$id = $post->ID;
       
  1146 	}
       
  1147 
       
  1148 	// @todo Consider exposing any errors, rather than having 'Saving draft...'
       
  1149 	$x = new WP_Ajax_Response( array(
       
  1150 		'what' => 'autosave',
       
  1151 		'id' => $id,
       
  1152 		'data' => $data,
       
  1153 		'supplemental' => $supplemental
       
  1154 	) );
       
  1155 	$x->send();
       
  1156 }
       
  1157 
       
  1158 function wp_ajax_closed_postboxes() {
       
  1159 	check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
       
  1160 	$closed = isset( $_POST['closed'] ) ? explode( ',', $_POST['closed']) : array();
       
  1161 	$closed = array_filter($closed);
       
  1162 
       
  1163 	$hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden']) : array();
       
  1164 	$hidden = array_filter($hidden);
       
  1165 
       
  1166 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
       
  1167 
       
  1168 	if ( $page != sanitize_key( $page ) )
       
  1169 		wp_die( 0 );
       
  1170 
       
  1171 	if ( ! $user = wp_get_current_user() )
       
  1172 		wp_die( -1 );
       
  1173 
       
  1174 	if ( is_array($closed) )
       
  1175 		update_user_option($user->ID, "closedpostboxes_$page", $closed, true);
       
  1176 
       
  1177 	if ( is_array($hidden) ) {
       
  1178 		$hidden = array_diff( $hidden, array('submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu') ); // postboxes that are always shown
       
  1179 		update_user_option($user->ID, "metaboxhidden_$page", $hidden, true);
       
  1180 	}
       
  1181 
       
  1182 	wp_die( 1 );
       
  1183 }
       
  1184 
       
  1185 function wp_ajax_hidden_columns() {
       
  1186 	check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
       
  1187 	$hidden = isset( $_POST['hidden'] ) ? $_POST['hidden'] : '';
       
  1188 	$hidden = explode( ',', $_POST['hidden'] );
       
  1189 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
       
  1190 
       
  1191 	if ( $page != sanitize_key( $page ) )
       
  1192 		wp_die( 0 );
       
  1193 
       
  1194 	if ( ! $user = wp_get_current_user() )
       
  1195 		wp_die( -1 );
       
  1196 
       
  1197 	if ( is_array($hidden) )
       
  1198 		update_user_option($user->ID, "manage{$page}columnshidden", $hidden, true);
       
  1199 
       
  1200 	wp_die( 1 );
       
  1201 }
       
  1202 
       
  1203 function wp_ajax_update_welcome_panel() {
       
  1204 	check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
       
  1205 
       
  1206 	if ( ! current_user_can( 'edit_theme_options' ) )
       
  1207 		wp_die( -1 );
       
  1208 
       
  1209 	update_user_meta( get_current_user_id(), 'show_welcome_panel', empty( $_POST['visible'] ) ? 0 : 1 );
       
  1210 
       
  1211 	wp_die( 1 );
       
  1212 }
       
  1213 
       
  1214 function wp_ajax_menu_get_metabox() {
       
  1215 	if ( ! current_user_can( 'edit_theme_options' ) )
       
  1216 		wp_die( -1 );
       
  1217 
       
  1218 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
       
  1219 
       
  1220 	if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
       
  1221 		$type = 'posttype';
       
  1222 		$callback = 'wp_nav_menu_item_post_type_meta_box';
       
  1223 		$items = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
       
  1224 	} elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
       
  1225 		$type = 'taxonomy';
       
  1226 		$callback = 'wp_nav_menu_item_taxonomy_meta_box';
       
  1227 		$items = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
       
  1228 	}
       
  1229 
       
  1230 	if ( ! empty( $_POST['item-object'] ) && isset( $items[$_POST['item-object']] ) ) {
       
  1231 		$menus_meta_box_object = $items[ $_POST['item-object'] ];
       
  1232 		/**
       
  1233 		 * Filter a nav menu meta box object.
       
  1234 		 *
       
  1235 		 * @since 3.0.0
       
  1236 		 *
       
  1237 		 * @param object $menus_meta_box_object A nav menu meta box object, such as Page, Post, Category, Tag, etc.
       
  1238 		 */
       
  1239 		$item = apply_filters( 'nav_menu_meta_box_object', $menus_meta_box_object );
       
  1240 		ob_start();
       
  1241 		call_user_func_array($callback, array(
       
  1242 			null,
       
  1243 			array(
       
  1244 				'id' => 'add-' . $item->name,
       
  1245 				'title' => $item->labels->name,
       
  1246 				'callback' => $callback,
       
  1247 				'args' => $item,
       
  1248 			)
       
  1249 		));
       
  1250 
       
  1251 		$markup = ob_get_clean();
       
  1252 
       
  1253 		echo json_encode(array(
       
  1254 			'replace-id' => $type . '-' . $item->name,
       
  1255 			'markup' => $markup,
       
  1256 		));
       
  1257 	}
       
  1258 
       
  1259 	wp_die();
       
  1260 }
       
  1261 
       
  1262 function wp_ajax_wp_link_ajax() {
       
  1263 	check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
       
  1264 
       
  1265 	$args = array();
       
  1266 
       
  1267 	if ( isset( $_POST['search'] ) )
       
  1268 		$args['s'] = wp_unslash( $_POST['search'] );
       
  1269 	$args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
       
  1270 
       
  1271 	require(ABSPATH . WPINC . '/class-wp-editor.php');
       
  1272 	$results = _WP_Editors::wp_link_query( $args );
       
  1273 
       
  1274 	if ( ! isset( $results ) )
       
  1275 		wp_die( 0 );
       
  1276 
       
  1277 	echo json_encode( $results );
       
  1278 	echo "\n";
       
  1279 
       
  1280 	wp_die();
       
  1281 }
       
  1282 
       
  1283 function wp_ajax_menu_locations_save() {
       
  1284 	if ( ! current_user_can( 'edit_theme_options' ) )
       
  1285 		wp_die( -1 );
       
  1286 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
       
  1287 	if ( ! isset( $_POST['menu-locations'] ) )
       
  1288 		wp_die( 0 );
       
  1289 	set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
       
  1290 	wp_die( 1 );
       
  1291 }
       
  1292 
       
  1293 function wp_ajax_meta_box_order() {
       
  1294 	check_ajax_referer( 'meta-box-order' );
       
  1295 	$order = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
       
  1296 	$page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
       
  1297 
       
  1298 	if ( $page_columns != 'auto' )
       
  1299 		$page_columns = (int) $page_columns;
       
  1300 
       
  1301 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
       
  1302 
       
  1303 	if ( $page != sanitize_key( $page ) )
       
  1304 		wp_die( 0 );
       
  1305 
       
  1306 	if ( ! $user = wp_get_current_user() )
       
  1307 		wp_die( -1 );
       
  1308 
       
  1309 	if ( $order )
       
  1310 		update_user_option($user->ID, "meta-box-order_$page", $order, true);
       
  1311 
       
  1312 	if ( $page_columns )
       
  1313 		update_user_option($user->ID, "screen_layout_$page", $page_columns, true);
       
  1314 
       
  1315 	wp_die( 1 );
       
  1316 }
       
  1317 
       
  1318 function wp_ajax_menu_quick_search() {
       
  1319 	if ( ! current_user_can( 'edit_theme_options' ) )
       
  1320 		wp_die( -1 );
       
  1321 
       
  1322 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
       
  1323 
       
  1324 	_wp_ajax_menu_quick_search( $_POST );
       
  1325 
       
  1326 	wp_die();
       
  1327 }
       
  1328 
       
  1329 function wp_ajax_get_permalink() {
       
  1330 	check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
       
  1331 	$post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
       
  1332 	wp_die( add_query_arg( array( 'preview' => 'true' ), get_permalink( $post_id ) ) );
       
  1333 }
       
  1334 
       
  1335 function wp_ajax_sample_permalink() {
       
  1336 	check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
       
  1337 	$post_id = isset($_POST['post_id'])? intval($_POST['post_id']) : 0;
       
  1338 	$title = isset($_POST['new_title'])? $_POST['new_title'] : '';
       
  1339 	$slug = isset($_POST['new_slug'])? $_POST['new_slug'] : null;
       
  1340 	wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
       
  1341 }
       
  1342 
       
  1343 function wp_ajax_inline_save() {
       
  1344 	global $wp_list_table;
       
  1345 
       
  1346 	check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
       
  1347 
       
  1348 	if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
       
  1349 		wp_die();
       
  1350 
       
  1351 	if ( 'page' == $_POST['post_type'] ) {
       
  1352 		if ( ! current_user_can( 'edit_page', $post_ID ) )
       
  1353 			wp_die( __( 'You are not allowed to edit this page.' ) );
       
  1354 	} else {
       
  1355 		if ( ! current_user_can( 'edit_post', $post_ID ) )
       
  1356 			wp_die( __( 'You are not allowed to edit this post.' ) );
       
  1357 	}
       
  1358 
       
  1359 	if ( $last = wp_check_post_lock( $post_ID ) ) {
       
  1360 		$last_user = get_userdata( $last );
       
  1361 		$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
       
  1362 		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 ) );
       
  1363 		wp_die();
       
  1364 	}
       
  1365 
       
  1366 	$data = &$_POST;
       
  1367 
       
  1368 	$post = get_post( $post_ID, ARRAY_A );
       
  1369 	$post = wp_slash($post); //since it is from db
       
  1370 
       
  1371 	$data['content'] = $post['post_content'];
       
  1372 	$data['excerpt'] = $post['post_excerpt'];
       
  1373 
       
  1374 	// rename
       
  1375 	$data['user_ID'] = get_current_user_id();
       
  1376 
       
  1377 	if ( isset($data['post_parent']) )
       
  1378 		$data['parent_id'] = $data['post_parent'];
       
  1379 
       
  1380 	// status
       
  1381 	if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
       
  1382 		$data['post_status'] = 'private';
       
  1383 	else
       
  1384 		$data['post_status'] = $data['_status'];
       
  1385 
       
  1386 	if ( empty($data['comment_status']) )
       
  1387 		$data['comment_status'] = 'closed';
       
  1388 	if ( empty($data['ping_status']) )
       
  1389 		$data['ping_status'] = 'closed';
       
  1390 
       
  1391 	// Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
       
  1392 	if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
       
  1393 		$post['post_status'] = 'publish';
       
  1394 		$data['post_name'] = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
       
  1395 	}
       
  1396 
       
  1397 	// update the post
       
  1398 	edit_post();
       
  1399 
       
  1400 	$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
       
  1401 
       
  1402 	$mode = $_POST['post_view'];
       
  1403 
       
  1404 	$level = 0;
       
  1405 	$request_post = array( get_post( $_POST['post_ID'] ) );
       
  1406 	$parent = $request_post[0]->post_parent;
       
  1407 
       
  1408 	while ( $parent > 0 ) {
       
  1409 		$parent_post = get_post( $parent );
       
  1410 		$parent = $parent_post->post_parent;
       
  1411 		$level++;
       
  1412 	}
       
  1413 
       
  1414 	$wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
       
  1415 
       
  1416 	wp_die();
       
  1417 }
       
  1418 
       
  1419 function wp_ajax_inline_save_tax() {
       
  1420 	global $wp_list_table;
       
  1421 
       
  1422 	check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
       
  1423 
       
  1424 	$taxonomy = sanitize_key( $_POST['taxonomy'] );
       
  1425 	$tax = get_taxonomy( $taxonomy );
       
  1426 	if ( ! $tax )
       
  1427 		wp_die( 0 );
       
  1428 
       
  1429 	if ( ! current_user_can( $tax->cap->edit_terms ) )
       
  1430 		wp_die( -1 );
       
  1431 
       
  1432 	$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
       
  1433 
       
  1434 	if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
       
  1435 		wp_die( -1 );
       
  1436 
       
  1437 	$tag = get_term( $id, $taxonomy );
       
  1438 	$_POST['description'] = $tag->description;
       
  1439 
       
  1440 	$updated = wp_update_term($id, $taxonomy, $_POST);
       
  1441 	if ( $updated && !is_wp_error($updated) ) {
       
  1442 		$tag = get_term( $updated['term_id'], $taxonomy );
       
  1443 		if ( !$tag || is_wp_error( $tag ) ) {
       
  1444 			if ( is_wp_error($tag) && $tag->get_error_message() )
       
  1445 				wp_die( $tag->get_error_message() );
       
  1446 			wp_die( __( 'Item not updated.' ) );
       
  1447 		}
       
  1448 	} else {
       
  1449 		if ( is_wp_error($updated) && $updated->get_error_message() )
       
  1450 			wp_die( $updated->get_error_message() );
       
  1451 		wp_die( __( 'Item not updated.' ) );
       
  1452 	}
       
  1453 	$level = 0;
       
  1454 	$parent = $tag->parent;
       
  1455 	while ( $parent > 0 ) {
       
  1456 		$parent_tag = get_term( $parent, $taxonomy );
       
  1457 		$parent = $parent_tag->parent;
       
  1458 		$level++;
       
  1459 	}
       
  1460 	$wp_list_table->single_row( $tag, $level );
       
  1461 	wp_die();
       
  1462 }
       
  1463 
       
  1464 function wp_ajax_find_posts() {
       
  1465 	global $wpdb;
       
  1466 
       
  1467 	check_ajax_referer( 'find-posts' );
       
  1468 
       
  1469 	$post_types = get_post_types( array( 'public' => true ), 'objects' );
       
  1470 	unset( $post_types['attachment'] );
       
  1471 
       
  1472 	$s = wp_unslash( $_POST['ps'] );
       
  1473 	$searchand = $search = '';
       
  1474 	$args = array(
       
  1475 		'post_type' => array_keys( $post_types ),
       
  1476 		'post_status' => 'any',
       
  1477 		'posts_per_page' => 50,
       
  1478 	);
       
  1479 	if ( '' !== $s )
       
  1480 		$args['s'] = $s;
       
  1481 
       
  1482 	$posts = get_posts( $args );
       
  1483 
       
  1484 	if ( ! $posts )
       
  1485 		wp_die( __('No items found.') );
       
  1486 
       
  1487 	$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>';
       
  1488 	foreach ( $posts as $post ) {
       
  1489 		$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
       
  1490 
       
  1491 		switch ( $post->post_status ) {
       
  1492 			case 'publish' :
       
  1493 			case 'private' :
       
  1494 				$stat = __('Published');
       
  1495 				break;
       
  1496 			case 'future' :
       
  1497 				$stat = __('Scheduled');
       
  1498 				break;
       
  1499 			case 'pending' :
       
  1500 				$stat = __('Pending Review');
       
  1501 				break;
       
  1502 			case 'draft' :
       
  1503 				$stat = __('Draft');
       
  1504 				break;
       
  1505 		}
       
  1506 
       
  1507 		if ( '0000-00-00 00:00:00' == $post->post_date ) {
       
  1508 			$time = '';
       
  1509 		} else {
       
  1510 			/* translators: date format in table columns, see http://php.net/date */
       
  1511 			$time = mysql2date(__('Y/m/d'), $post->post_date);
       
  1512 		}
       
  1513 
       
  1514 		$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>';
       
  1515 		$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";
       
  1516 	}
       
  1517 
       
  1518 	$html .= '</tbody></table>';
       
  1519 
       
  1520 	$x = new WP_Ajax_Response();
       
  1521 	$x->add( array(
       
  1522 		'data' => $html
       
  1523 	));
       
  1524 	$x->send();
       
  1525 }
       
  1526 
       
  1527 function wp_ajax_widgets_order() {
       
  1528 	check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
       
  1529 
       
  1530 	if ( !current_user_can('edit_theme_options') )
       
  1531 		wp_die( -1 );
       
  1532 
       
  1533 	unset( $_POST['savewidgets'], $_POST['action'] );
       
  1534 
       
  1535 	// save widgets order for all sidebars
       
  1536 	if ( is_array($_POST['sidebars']) ) {
       
  1537 		$sidebars = array();
       
  1538 		foreach ( $_POST['sidebars'] as $key => $val ) {
       
  1539 			$sb = array();
       
  1540 			if ( !empty($val) ) {
       
  1541 				$val = explode(',', $val);
       
  1542 				foreach ( $val as $k => $v ) {
       
  1543 					if ( strpos($v, 'widget-') === false )
       
  1544 						continue;
       
  1545 
       
  1546 					$sb[$k] = substr($v, strpos($v, '_') + 1);
       
  1547 				}
       
  1548 			}
       
  1549 			$sidebars[$key] = $sb;
       
  1550 		}
       
  1551 		wp_set_sidebars_widgets($sidebars);
       
  1552 		wp_die( 1 );
       
  1553 	}
       
  1554 
       
  1555 	wp_die( -1 );
       
  1556 }
       
  1557 
       
  1558 function wp_ajax_save_widget() {
       
  1559 	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_updates;
       
  1560 
       
  1561 	check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
       
  1562 
       
  1563 	if ( !current_user_can('edit_theme_options') || !isset($_POST['id_base']) )
       
  1564 		wp_die( -1 );
       
  1565 
       
  1566 	unset( $_POST['savewidgets'], $_POST['action'] );
       
  1567 
       
  1568 	/**
       
  1569 	 * Fires early when editing the widgets displayed in sidebars.
       
  1570 	 *
       
  1571 	 * @since 2.8.0
       
  1572 	 */
       
  1573 	do_action( 'load-widgets.php' );
       
  1574 
       
  1575 	/**
       
  1576 	 * Fires early when editing the widgets displayed in sidebars.
       
  1577 	 *
       
  1578 	 * @since 2.8.0
       
  1579 	 */
       
  1580 	do_action( 'widgets.php' );
       
  1581 
       
  1582 	/**
       
  1583 	 * Fires early when editing the widgets displayed in sidebars.
       
  1584 	 *
       
  1585 	 * @since 2.2.0
       
  1586 	 */
       
  1587 	do_action( 'sidebar_admin_setup' );
       
  1588 
       
  1589 	$id_base = $_POST['id_base'];
       
  1590 	$widget_id = $_POST['widget-id'];
       
  1591 	$sidebar_id = $_POST['sidebar'];
       
  1592 	$multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
       
  1593 	$settings = isset($_POST['widget-' . $id_base]) && is_array($_POST['widget-' . $id_base]) ? $_POST['widget-' . $id_base] : false;
       
  1594 	$error = '<p>' . __('An error has occurred. Please reload the page and try again.') . '</p>';
       
  1595 
       
  1596 	$sidebars = wp_get_sidebars_widgets();
       
  1597 	$sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
       
  1598 
       
  1599 	// delete
       
  1600 	if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
       
  1601 
       
  1602 		if ( !isset($wp_registered_widgets[$widget_id]) )
       
  1603 			wp_die( $error );
       
  1604 
       
  1605 		$sidebar = array_diff( $sidebar, array($widget_id) );
       
  1606 		$_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
       
  1607 	} elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
       
  1608 		if ( !$multi_number )
       
  1609 			wp_die( $error );
       
  1610 
       
  1611 		$_POST['widget-' . $id_base] = array( $multi_number => array_shift($settings) );
       
  1612 		$widget_id = $id_base . '-' . $multi_number;
       
  1613 		$sidebar[] = $widget_id;
       
  1614 	}
       
  1615 	$_POST['widget-id'] = $sidebar;
       
  1616 
       
  1617 	foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
       
  1618 
       
  1619 		if ( $name == $id_base ) {
       
  1620 			if ( !is_callable( $control['callback'] ) )
       
  1621 				continue;
       
  1622 
       
  1623 			ob_start();
       
  1624 				call_user_func_array( $control['callback'], $control['params'] );
       
  1625 			ob_end_clean();
       
  1626 			break;
       
  1627 		}
       
  1628 	}
       
  1629 
       
  1630 	if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
       
  1631 		$sidebars[$sidebar_id] = $sidebar;
       
  1632 		wp_set_sidebars_widgets($sidebars);
       
  1633 		echo "deleted:$widget_id";
       
  1634 		wp_die();
       
  1635 	}
       
  1636 
       
  1637 	if ( !empty($_POST['add_new']) )
       
  1638 		wp_die();
       
  1639 
       
  1640 	if ( $form = $wp_registered_widget_controls[$widget_id] )
       
  1641 		call_user_func_array( $form['callback'], $form['params'] );
       
  1642 
       
  1643 	wp_die();
       
  1644 }
       
  1645 
       
  1646 function wp_ajax_upload_attachment() {
       
  1647 	check_ajax_referer( 'media-form' );
       
  1648 
       
  1649 	if ( ! current_user_can( 'upload_files' ) )
       
  1650 		wp_die();
       
  1651 
       
  1652 	if ( isset( $_REQUEST['post_id'] ) ) {
       
  1653 		$post_id = $_REQUEST['post_id'];
       
  1654 		if ( ! current_user_can( 'edit_post', $post_id ) )
       
  1655 			wp_die();
       
  1656 	} else {
       
  1657 		$post_id = null;
       
  1658 	}
       
  1659 
       
  1660 	$post_data = isset( $_REQUEST['post_data'] ) ? $_REQUEST['post_data'] : array();
       
  1661 
       
  1662 	// If the context is custom header or background, make sure the uploaded file is an image.
       
  1663 	if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
       
  1664 		$wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'], false );
       
  1665 		if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
       
  1666 			echo json_encode( array(
       
  1667 				'success' => false,
       
  1668 				'data'    => array(
       
  1669 					'message'  => __( 'The uploaded file is not a valid image. Please try again.' ),
       
  1670 					'filename' => $_FILES['async-upload']['name'],
       
  1671 				)
       
  1672 			) );
       
  1673 
       
  1674 			wp_die();
       
  1675 		}
       
  1676 	}
       
  1677 
       
  1678 	$attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );
       
  1679 
       
  1680 	if ( is_wp_error( $attachment_id ) ) {
       
  1681 		echo json_encode( array(
       
  1682 			'success' => false,
       
  1683 			'data'    => array(
       
  1684 				'message'  => $attachment_id->get_error_message(),
       
  1685 				'filename' => $_FILES['async-upload']['name'],
       
  1686 			)
       
  1687 		) );
       
  1688 
       
  1689 		wp_die();
       
  1690 	}
       
  1691 
       
  1692 	if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
       
  1693 		if ( 'custom-background' === $post_data['context'] )
       
  1694 			update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', $post_data['theme'] );
       
  1695 
       
  1696 		if ( 'custom-header' === $post_data['context'] )
       
  1697 			update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
       
  1698 	}
       
  1699 
       
  1700 	if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) )
       
  1701 		wp_die();
       
  1702 
       
  1703 	echo json_encode( array(
       
  1704 		'success' => true,
       
  1705 		'data'    => $attachment,
       
  1706 	) );
       
  1707 
       
  1708 	wp_die();
       
  1709 }
       
  1710 
       
  1711 function wp_ajax_image_editor() {
       
  1712 	$attachment_id = intval($_POST['postid']);
       
  1713 	if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
       
  1714 		wp_die( -1 );
       
  1715 
       
  1716 	check_ajax_referer( "image_editor-$attachment_id" );
       
  1717 	include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
       
  1718 
       
  1719 	$msg = false;
       
  1720 	switch ( $_POST['do'] ) {
       
  1721 		case 'save' :
       
  1722 			$msg = wp_save_image($attachment_id);
       
  1723 			$msg = json_encode($msg);
       
  1724 			wp_die( $msg );
       
  1725 			break;
       
  1726 		case 'scale' :
       
  1727 			$msg = wp_save_image($attachment_id);
       
  1728 			break;
       
  1729 		case 'restore' :
       
  1730 			$msg = wp_restore_image($attachment_id);
       
  1731 			break;
       
  1732 	}
       
  1733 
       
  1734 	wp_image_editor($attachment_id, $msg);
       
  1735 	wp_die();
       
  1736 }
       
  1737 
       
  1738 function wp_ajax_set_post_thumbnail() {
       
  1739 	$json = ! empty( $_REQUEST['json'] ); // New-style request
       
  1740 
       
  1741 	$post_ID = intval( $_POST['post_id'] );
       
  1742 	if ( ! current_user_can( 'edit_post', $post_ID ) )
       
  1743 		wp_die( -1 );
       
  1744 
       
  1745 	$thumbnail_id = intval( $_POST['thumbnail_id'] );
       
  1746 
       
  1747 	if ( $json )
       
  1748 		check_ajax_referer( "update-post_$post_ID" );
       
  1749 	else
       
  1750 		check_ajax_referer( "set_post_thumbnail-$post_ID" );
       
  1751 
       
  1752 	if ( $thumbnail_id == '-1' ) {
       
  1753 		if ( delete_post_thumbnail( $post_ID ) ) {
       
  1754 			$return = _wp_post_thumbnail_html( null, $post_ID );
       
  1755 			$json ? wp_send_json_success( $return ) : wp_die( $return );
       
  1756 		} else {
       
  1757 			wp_die( 0 );
       
  1758 		}
       
  1759 	}
       
  1760 
       
  1761 	if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) {
       
  1762 		$return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
       
  1763 		$json ? wp_send_json_success( $return ) : wp_die( $return );
       
  1764 	}
       
  1765 
       
  1766 	wp_die( 0 );
       
  1767 }
       
  1768 
       
  1769 function wp_ajax_date_format() {
       
  1770 	wp_die( date_i18n( sanitize_option( 'date_format', $_POST['date'] ) ) );
       
  1771 }
       
  1772 
       
  1773 function wp_ajax_time_format() {
       
  1774 	wp_die( date_i18n( sanitize_option( 'time_format', $_POST['date'] ) ) );
       
  1775 }
       
  1776 
       
  1777 function wp_ajax_wp_fullscreen_save_post() {
       
  1778 	$post_id = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
       
  1779 
       
  1780 	$post = $post_type = null;
       
  1781 
       
  1782 	if ( $post_id )
       
  1783 		$post = get_post( $post_id );
       
  1784 
       
  1785 	if ( $post )
       
  1786 		$post_type = $post->post_type;
       
  1787 	elseif ( isset( $_POST['post_type'] ) && post_type_exists( $_POST['post_type'] ) )
       
  1788 		$post_type = $_POST['post_type'];
       
  1789 
       
  1790 	check_ajax_referer('update-post_' . $post_id, '_wpnonce');
       
  1791 
       
  1792 	$post_id = edit_post();
       
  1793 
       
  1794 	if ( is_wp_error($post_id) ) {
       
  1795 		if ( $post_id->get_error_message() )
       
  1796 			$message = $post_id->get_error_message();
       
  1797 		else
       
  1798 			$message = __('Save failed');
       
  1799 
       
  1800 		echo json_encode( array( 'message' => $message, 'last_edited' => '' ) );
       
  1801 		wp_die();
       
  1802 	} else {
       
  1803 		$message = __('Saved.');
       
  1804 	}
       
  1805 
       
  1806 	if ( $post ) {
       
  1807 		$last_date = mysql2date( get_option('date_format'), $post->post_modified );
       
  1808 		$last_time = mysql2date( get_option('time_format'), $post->post_modified );
       
  1809 	} else {
       
  1810 		$last_date = date_i18n( get_option('date_format') );
       
  1811 		$last_time = date_i18n( get_option('time_format') );
       
  1812 	}
       
  1813 
       
  1814 	if ( $last_id = get_post_meta($post_id, '_edit_last', true) ) {
       
  1815 		$last_user = get_userdata($last_id);
       
  1816 		$last_edited = sprintf( __('Last edited by %1$s on %2$s at %3$s'), esc_html( $last_user->display_name ), $last_date, $last_time );
       
  1817 	} else {
       
  1818 		$last_edited = sprintf( __('Last edited on %1$s at %2$s'), $last_date, $last_time );
       
  1819 	}
       
  1820 
       
  1821 	echo json_encode( array( 'message' => $message, 'last_edited' => $last_edited ) );
       
  1822 	wp_die();
       
  1823 }
       
  1824 
       
  1825 function wp_ajax_wp_remove_post_lock() {
       
  1826 	if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) )
       
  1827 		wp_die( 0 );
       
  1828 	$post_id = (int) $_POST['post_ID'];
       
  1829 	if ( ! $post = get_post( $post_id ) )
       
  1830 		wp_die( 0 );
       
  1831 
       
  1832 	check_ajax_referer( 'update-post_' . $post_id );
       
  1833 
       
  1834 	if ( ! current_user_can( 'edit_post', $post_id ) )
       
  1835 		wp_die( -1 );
       
  1836 
       
  1837 	$active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
       
  1838 	if ( $active_lock[1] != get_current_user_id() )
       
  1839 		wp_die( 0 );
       
  1840 
       
  1841 	/**
       
  1842 	 * Filter the post lock window duration.
       
  1843 	 *
       
  1844 	 * @since 3.3.0
       
  1845 	 *
       
  1846 	 * @param int $interval The interval in seconds the post lock duration should last, plus 5 seconds. Default 120.
       
  1847 	 */
       
  1848 	$new_lock = ( time() - apply_filters( 'wp_check_post_lock_window', 120 ) + 5 ) . ':' . $active_lock[1];
       
  1849 	update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
       
  1850 	wp_die( 1 );
       
  1851 }
       
  1852 
       
  1853 function wp_ajax_dismiss_wp_pointer() {
       
  1854 	$pointer = $_POST['pointer'];
       
  1855 	if ( $pointer != sanitize_key( $pointer ) )
       
  1856 		wp_die( 0 );
       
  1857 
       
  1858 //	check_ajax_referer( 'dismiss-pointer_' . $pointer );
       
  1859 
       
  1860 	$dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
       
  1861 
       
  1862 	if ( in_array( $pointer, $dismissed ) )
       
  1863 		wp_die( 0 );
       
  1864 
       
  1865 	$dismissed[] = $pointer;
       
  1866 	$dismissed = implode( ',', $dismissed );
       
  1867 
       
  1868 	update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
       
  1869 	wp_die( 1 );
       
  1870 }
       
  1871 
       
  1872 /**
       
  1873  * Get an attachment.
       
  1874  *
       
  1875  * @since 3.5.0
       
  1876  */
       
  1877 function wp_ajax_get_attachment() {
       
  1878 	if ( ! isset( $_REQUEST['id'] ) )
       
  1879 		wp_send_json_error();
       
  1880 
       
  1881 	if ( ! $id = absint( $_REQUEST['id'] ) )
       
  1882 		wp_send_json_error();
       
  1883 
       
  1884 	if ( ! $post = get_post( $id ) )
       
  1885 		wp_send_json_error();
       
  1886 
       
  1887 	if ( 'attachment' != $post->post_type )
       
  1888 		wp_send_json_error();
       
  1889 
       
  1890 	if ( ! current_user_can( 'upload_files' ) )
       
  1891 		wp_send_json_error();
       
  1892 
       
  1893 	if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
       
  1894 		wp_send_json_error();
       
  1895 
       
  1896 	wp_send_json_success( $attachment );
       
  1897 }
       
  1898 
       
  1899 /**
       
  1900  * Query for attachments.
       
  1901  *
       
  1902  * @since 3.5.0
       
  1903  */
       
  1904 function wp_ajax_query_attachments() {
       
  1905 	if ( ! current_user_can( 'upload_files' ) )
       
  1906 		wp_send_json_error();
       
  1907 
       
  1908 	$query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
       
  1909 	$query = array_intersect_key( $query, array_flip( array(
       
  1910 		's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
       
  1911 		'post_parent', 'post__in', 'post__not_in',
       
  1912 	) ) );
       
  1913 
       
  1914 	$query['post_type'] = 'attachment';
       
  1915 	$query['post_status'] = 'inherit';
       
  1916 	if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) )
       
  1917 		$query['post_status'] .= ',private';
       
  1918 
       
  1919 	/**
       
  1920 	 * Filter the arguments passed to WP_Query during an AJAX call for querying attachments.
       
  1921 	 *
       
  1922 	 * @since 3.7.0
       
  1923 	 *
       
  1924 	 * @param array $query An array of query variables. @see WP_Query::parse_query()
       
  1925 	 */
       
  1926 	$query = apply_filters( 'ajax_query_attachments_args', $query );
       
  1927 	$query = new WP_Query( $query );
       
  1928 
       
  1929 	$posts = array_map( 'wp_prepare_attachment_for_js', $query->posts );
       
  1930 	$posts = array_filter( $posts );
       
  1931 
       
  1932 	wp_send_json_success( $posts );
       
  1933 }
       
  1934 
       
  1935 /**
       
  1936  * Save attachment attributes.
       
  1937  *
       
  1938  * @since 3.5.0
       
  1939  */
       
  1940 function wp_ajax_save_attachment() {
       
  1941 	if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) )
       
  1942 		wp_send_json_error();
       
  1943 
       
  1944 	if ( ! $id = absint( $_REQUEST['id'] ) )
       
  1945 		wp_send_json_error();
       
  1946 
       
  1947 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
       
  1948 
       
  1949 	if ( ! current_user_can( 'edit_post', $id ) )
       
  1950 		wp_send_json_error();
       
  1951 
       
  1952 	$changes = $_REQUEST['changes'];
       
  1953 	$post    = get_post( $id, ARRAY_A );
       
  1954 
       
  1955 	if ( 'attachment' != $post['post_type'] )
       
  1956 		wp_send_json_error();
       
  1957 
       
  1958 	if ( isset( $changes['title'] ) )
       
  1959 		$post['post_title'] = $changes['title'];
       
  1960 
       
  1961 	if ( isset( $changes['caption'] ) )
       
  1962 		$post['post_excerpt'] = $changes['caption'];
       
  1963 
       
  1964 	if ( isset( $changes['description'] ) )
       
  1965 		$post['post_content'] = $changes['description'];
       
  1966 
       
  1967 	if ( isset( $changes['alt'] ) ) {
       
  1968 		$alt = wp_unslash( $changes['alt'] );
       
  1969 		if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) {
       
  1970 			$alt = wp_strip_all_tags( $alt, true );
       
  1971 			update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) );
       
  1972 		}
       
  1973 	}
       
  1974 
       
  1975 	wp_update_post( $post );
       
  1976 	wp_send_json_success();
       
  1977 }
       
  1978 
       
  1979 /**
       
  1980  * Save backwards compatible attachment attributes.
       
  1981  *
       
  1982  * @since 3.5.0
       
  1983  */
       
  1984 function wp_ajax_save_attachment_compat() {
       
  1985 	if ( ! isset( $_REQUEST['id'] ) )
       
  1986 		wp_send_json_error();
       
  1987 
       
  1988 	if ( ! $id = absint( $_REQUEST['id'] ) )
       
  1989 		wp_send_json_error();
       
  1990 
       
  1991 	if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) )
       
  1992 		wp_send_json_error();
       
  1993 	$attachment_data = $_REQUEST['attachments'][ $id ];
       
  1994 
       
  1995 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
       
  1996 
       
  1997 	if ( ! current_user_can( 'edit_post', $id ) )
       
  1998 		wp_send_json_error();
       
  1999 
       
  2000 	$post = get_post( $id, ARRAY_A );
       
  2001 
       
  2002 	if ( 'attachment' != $post['post_type'] )
       
  2003 		wp_send_json_error();
       
  2004 
       
  2005 	/** This filter is documented in wp-admin/includes/media.php */
       
  2006 	$post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
       
  2007 
       
  2008 	if ( isset( $post['errors'] ) ) {
       
  2009 		$errors = $post['errors']; // @todo return me and display me!
       
  2010 		unset( $post['errors'] );
       
  2011 	}
       
  2012 
       
  2013 	wp_update_post( $post );
       
  2014 
       
  2015 	foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
       
  2016 		if ( isset( $attachment_data[ $taxonomy ] ) )
       
  2017 			wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
       
  2018 	}
       
  2019 
       
  2020 	if ( ! $attachment = wp_prepare_attachment_for_js( $id ) )
       
  2021 		wp_send_json_error();
       
  2022 
       
  2023 	wp_send_json_success( $attachment );
       
  2024 }
       
  2025 
       
  2026 function wp_ajax_save_attachment_order() {
       
  2027 	if ( ! isset( $_REQUEST['post_id'] ) )
       
  2028 		wp_send_json_error();
       
  2029 
       
  2030 	if ( ! $post_id = absint( $_REQUEST['post_id'] ) )
       
  2031 		wp_send_json_error();
       
  2032 
       
  2033 	if ( empty( $_REQUEST['attachments'] ) )
       
  2034 		wp_send_json_error();
       
  2035 
       
  2036 	check_ajax_referer( 'update-post_' . $post_id, 'nonce' );
       
  2037 
       
  2038 	$attachments = $_REQUEST['attachments'];
       
  2039 
       
  2040 	if ( ! current_user_can( 'edit_post', $post_id ) )
       
  2041 		wp_send_json_error();
       
  2042 
       
  2043 	$post = get_post( $post_id, ARRAY_A );
       
  2044 
       
  2045 	foreach ( $attachments as $attachment_id => $menu_order ) {
       
  2046 		if ( ! current_user_can( 'edit_post', $attachment_id ) )
       
  2047 			continue;
       
  2048 		if ( ! $attachment = get_post( $attachment_id ) )
       
  2049 			continue;
       
  2050 		if ( 'attachment' != $attachment->post_type )
       
  2051 			continue;
       
  2052 
       
  2053 		wp_update_post( array( 'ID' => $attachment_id, 'menu_order' => $menu_order ) );
       
  2054 	}
       
  2055 
       
  2056 	wp_send_json_success();
       
  2057 }
       
  2058 
       
  2059 /**
       
  2060  * Generates the HTML to send an attachment to the editor.
       
  2061  * Backwards compatible with the media_send_to_editor filter and the chain
       
  2062  * of filters that follow.
       
  2063  *
       
  2064  * @since 3.5.0
       
  2065  */
       
  2066 function wp_ajax_send_attachment_to_editor() {
       
  2067 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
       
  2068 
       
  2069 	$attachment = wp_unslash( $_POST['attachment'] );
       
  2070 
       
  2071 	$id = intval( $attachment['id'] );
       
  2072 
       
  2073 	if ( ! $post = get_post( $id ) )
       
  2074 		wp_send_json_error();
       
  2075 
       
  2076 	if ( 'attachment' != $post->post_type )
       
  2077 		wp_send_json_error();
       
  2078 
       
  2079 	if ( current_user_can( 'edit_post', $id ) ) {
       
  2080 		// If this attachment is unattached, attach it. Primarily a back compat thing.
       
  2081 		if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) {
       
  2082 			wp_update_post( array( 'ID' => $id, 'post_parent' => $insert_into_post_id ) );
       
  2083 		}
       
  2084 	}
       
  2085 
       
  2086 	$rel = $url = '';
       
  2087 	$html = $title = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
       
  2088 	if ( ! empty( $attachment['url'] ) ) {
       
  2089 		$url = $attachment['url'];
       
  2090 		if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url )
       
  2091 			$rel = ' rel="attachment wp-att-' . $id . '"';
       
  2092 		$html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
       
  2093 	}
       
  2094 
       
  2095 	remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' );
       
  2096 
       
  2097 	if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
       
  2098 		$align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
       
  2099 		$size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
       
  2100 		$alt = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
       
  2101 		$caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
       
  2102 		$title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
       
  2103 		$html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
       
  2104 	} elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 )  ) {
       
  2105 		$html = stripslashes_deep( $_POST['html'] );
       
  2106 	}
       
  2107 
       
  2108 	/** This filter is documented in wp-admin/includes/media.php */
       
  2109 	$html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
       
  2110 
       
  2111 	wp_send_json_success( $html );
       
  2112 }
       
  2113 
       
  2114 /**
       
  2115  * Generates the HTML to send a non-image embed link to the editor.
       
  2116  *
       
  2117  * Backwards compatible with the following filters:
       
  2118  * - file_send_to_editor_url
       
  2119  * - audio_send_to_editor_url
       
  2120  * - video_send_to_editor_url
       
  2121  *
       
  2122  * @since 3.5.0
       
  2123  */
       
  2124 function wp_ajax_send_link_to_editor() {
       
  2125 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
       
  2126 
       
  2127 	if ( ! $src = wp_unslash( $_POST['src'] ) )
       
  2128 		wp_send_json_error();
       
  2129 
       
  2130 	if ( ! strpos( $src, '://' ) )
       
  2131 		$src = 'http://' . $src;
       
  2132 
       
  2133 	if ( ! $src = esc_url_raw( $src ) )
       
  2134 		wp_send_json_error();
       
  2135 
       
  2136 	if ( ! $title = trim( wp_unslash( $_POST['title'] ) ) )
       
  2137 		$title = wp_basename( $src );
       
  2138 
       
  2139 	$html = '';
       
  2140 	if ( $title )
       
  2141 		$html = '<a href="' . esc_url( $src ) . '">' . $title . '</a>';
       
  2142 
       
  2143 	// Figure out what filter to run:
       
  2144 	$type = 'file';
       
  2145 	if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) )
       
  2146 		&& ( 'audio' == $ext_type || 'video' == $ext_type ) )
       
  2147 			$type = $ext_type;
       
  2148 
       
  2149 	/** This filter is documented in wp-admin/includes/media.php */
       
  2150 	$html = apply_filters( $type . '_send_to_editor_url', $html, $src, $title );
       
  2151 
       
  2152 	wp_send_json_success( $html );
       
  2153 }
       
  2154 
       
  2155 /**
       
  2156  * Heartbeat API (experimental)
       
  2157  *
       
  2158  * Runs when the user is logged in.
       
  2159  */
       
  2160 function wp_ajax_heartbeat() {
       
  2161 	if ( empty( $_POST['_nonce'] ) )
       
  2162 		wp_send_json_error();
       
  2163 
       
  2164 	$response = array();
       
  2165 
       
  2166 	if ( false === wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' ) ) {
       
  2167 		// User is logged in but nonces have expired.
       
  2168 		$response['nonces_expired'] = true;
       
  2169 		wp_send_json($response);
       
  2170 	}
       
  2171 
       
  2172 	// screen_id is the same as $current_screen->id and the JS global 'pagenow'
       
  2173 	if ( ! empty($_POST['screen_id']) )
       
  2174 		$screen_id = sanitize_key($_POST['screen_id']);
       
  2175 	else
       
  2176 		$screen_id = 'front';
       
  2177 
       
  2178 	if ( ! empty($_POST['data']) ) {
       
  2179 		$data = (array) $_POST['data'];
       
  2180 
       
  2181 		/**
       
  2182 		 * Filter the Heartbeat response received.
       
  2183 		 *
       
  2184 		 * @since 3.6.0
       
  2185 		 *
       
  2186 		 * @param array|object $response  The Heartbeat response object or array.
       
  2187 		 * @param array        $data      The $_POST data sent.
       
  2188 		 * @param string       $screen_id The screen id.
       
  2189 		 */
       
  2190 		$response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
       
  2191 	}
       
  2192 
       
  2193 	/**
       
  2194 	 * Filter the Heartbeat response sent.
       
  2195 	 *
       
  2196 	 * @since 3.6.0
       
  2197 	 *
       
  2198 	 * @param array|object $response  The Heartbeat response object or array.
       
  2199 	 * @param string       $screen_id The screen id.
       
  2200 	 */
       
  2201 	$response = apply_filters( 'heartbeat_send', $response, $screen_id );
       
  2202 
       
  2203 	/**
       
  2204 	 * Fires when Heartbeat ticks in logged-in environments.
       
  2205 	 *
       
  2206 	 * Allows the transport to be easily replaced with long-polling.
       
  2207 	 *
       
  2208 	 * @since 3.6.0
       
  2209 	 *
       
  2210 	 * @param array|object $response  The Heartbeat response object or array.
       
  2211 	 * @param string       $screen_id The screen id.
       
  2212 	 */
       
  2213 	do_action( 'heartbeat_tick', $response, $screen_id );
       
  2214 
       
  2215 	// Send the current time according to the server
       
  2216 	$response['server_time'] = time();
       
  2217 
       
  2218 	wp_send_json($response);
       
  2219 }
       
  2220 
       
  2221 function wp_ajax_get_revision_diffs() {
       
  2222 	require ABSPATH . 'wp-admin/includes/revision.php';
       
  2223 
       
  2224 	if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) )
       
  2225 		wp_send_json_error();
       
  2226 
       
  2227 	if ( ! current_user_can( 'read_post', $post->ID ) )
       
  2228 		wp_send_json_error();
       
  2229 
       
  2230 	// Really just pre-loading the cache here.
       
  2231 	if ( ! $revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) ) )
       
  2232 		wp_send_json_error();
       
  2233 
       
  2234 	$return = array();
       
  2235 	@set_time_limit( 0 );
       
  2236 
       
  2237 	foreach ( $_REQUEST['compare'] as $compare_key ) {
       
  2238 		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
       
  2239 
       
  2240 		$return[] = array(
       
  2241 			'id' => $compare_key,
       
  2242 			'fields' => wp_get_revision_ui_diff( $post, $compare_from, $compare_to ),
       
  2243 		);
       
  2244 	}
       
  2245 	wp_send_json_success( $return );
       
  2246 }