wp/wp-admin/includes/ajax-actions.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    10 //
    10 //
    11 // No-privilege Ajax handlers.
    11 // No-privilege Ajax handlers.
    12 //
    12 //
    13 
    13 
    14 /**
    14 /**
    15  * Ajax handler for the Heartbeat API in the no-privilege context.
    15  * Handles the Heartbeat API in the no-privilege context via AJAX .
    16  *
    16  *
    17  * Runs when the user is not logged in.
    17  * Runs when the user is not logged in.
    18  *
    18  *
    19  * @since 3.6.0
    19  * @since 3.6.0
    20  */
    20  */
    74 //
    74 //
    75 // GET-based Ajax handlers.
    75 // GET-based Ajax handlers.
    76 //
    76 //
    77 
    77 
    78 /**
    78 /**
    79  * Ajax handler for fetching a list table.
    79  * Handles fetching a list table via AJAX.
    80  *
    80  *
    81  * @since 3.1.0
    81  * @since 3.1.0
    82  */
    82  */
    83 function wp_ajax_fetch_list() {
    83 function wp_ajax_fetch_list() {
    84 	$list_class = $_GET['list_args']['class'];
    84 	$list_class = $_GET['list_args']['class'];
    97 
    97 
    98 	wp_die( 0 );
    98 	wp_die( 0 );
    99 }
    99 }
   100 
   100 
   101 /**
   101 /**
   102  * Ajax handler for tag search.
   102  * Handles tag search via AJAX.
   103  *
   103  *
   104  * @since 3.1.0
   104  * @since 3.1.0
   105  */
   105  */
   106 function wp_ajax_ajax_tag_search() {
   106 function wp_ajax_ajax_tag_search() {
   107 	if ( ! isset( $_GET['tax'] ) ) {
   107 	if ( ! isset( $_GET['tax'] ) ) {
   108 		wp_die( 0 );
   108 		wp_die( 0 );
   109 	}
   109 	}
   110 
   110 
   111 	$taxonomy = sanitize_key( $_GET['tax'] );
   111 	$taxonomy        = sanitize_key( $_GET['tax'] );
   112 	$tax      = get_taxonomy( $taxonomy );
   112 	$taxonomy_object = get_taxonomy( $taxonomy );
   113 
   113 
   114 	if ( ! $tax ) {
   114 	if ( ! $taxonomy_object ) {
   115 		wp_die( 0 );
   115 		wp_die( 0 );
   116 	}
   116 	}
   117 
   117 
   118 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
   118 	if ( ! current_user_can( $taxonomy_object->cap->assign_terms ) ) {
   119 		wp_die( -1 );
   119 		wp_die( -1 );
   120 	}
   120 	}
   121 
   121 
   122 	$s = wp_unslash( $_GET['q'] );
   122 	$search = wp_unslash( $_GET['q'] );
   123 
   123 
   124 	$comma = _x( ',', 'tag delimiter' );
   124 	$comma = _x( ',', 'tag delimiter' );
   125 	if ( ',' !== $comma ) {
   125 	if ( ',' !== $comma ) {
   126 		$s = str_replace( $comma, ',', $s );
   126 		$search = str_replace( $comma, ',', $search );
   127 	}
   127 	}
   128 
   128 
   129 	if ( false !== strpos( $s, ',' ) ) {
   129 	if ( str_contains( $search, ',' ) ) {
   130 		$s = explode( ',', $s );
   130 		$search = explode( ',', $search );
   131 		$s = $s[ count( $s ) - 1 ];
   131 		$search = $search[ count( $search ) - 1 ];
   132 	}
   132 	}
   133 
   133 
   134 	$s = trim( $s );
   134 	$search = trim( $search );
   135 
   135 
   136 	/**
   136 	/**
   137 	 * Filters the minimum number of characters required to fire a tag search via Ajax.
   137 	 * Filters the minimum number of characters required to fire a tag search via Ajax.
   138 	 *
   138 	 *
   139 	 * @since 4.0.0
   139 	 * @since 4.0.0
   140 	 *
   140 	 *
   141 	 * @param int         $characters The minimum number of characters required. Default 2.
   141 	 * @param int         $characters      The minimum number of characters required. Default 2.
   142 	 * @param WP_Taxonomy $tax        The taxonomy object.
   142 	 * @param WP_Taxonomy $taxonomy_object The taxonomy object.
   143 	 * @param string      $s          The search term.
   143 	 * @param string      $search          The search term.
   144 	 */
   144 	 */
   145 	$term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s );
   145 	$term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $taxonomy_object, $search );
   146 
   146 
   147 	/*
   147 	/*
   148 	 * Require $term_search_min_chars chars for matching (default: 2)
   148 	 * Require $term_search_min_chars chars for matching (default: 2)
   149 	 * ensure it's a non-negative, non-zero integer.
   149 	 * ensure it's a non-negative, non-zero integer.
   150 	 */
   150 	 */
   151 	if ( ( 0 == $term_search_min_chars ) || ( strlen( $s ) < $term_search_min_chars ) ) {
   151 	if ( ( 0 === $term_search_min_chars ) || ( strlen( $search ) < $term_search_min_chars ) ) {
   152 		wp_die();
   152 		wp_die();
   153 	}
   153 	}
   154 
   154 
   155 	$results = get_terms(
   155 	$results = get_terms(
   156 		array(
   156 		array(
   157 			'taxonomy'   => $taxonomy,
   157 			'taxonomy'   => $taxonomy,
   158 			'name__like' => $s,
   158 			'name__like' => $search,
   159 			'fields'     => 'names',
   159 			'fields'     => 'names',
   160 			'hide_empty' => false,
   160 			'hide_empty' => false,
   161 			'number'     => isset( $_GET['number'] ) ? (int) $_GET['number'] : 0,
   161 			'number'     => isset( $_GET['number'] ) ? (int) $_GET['number'] : 0,
   162 		)
   162 		)
   163 	);
   163 	);
   164 
   164 
       
   165 	/**
       
   166 	 * Filters the Ajax term search results.
       
   167 	 *
       
   168 	 * @since 6.1.0
       
   169 	 *
       
   170 	 * @param string[]    $results         Array of term names.
       
   171 	 * @param WP_Taxonomy $taxonomy_object The taxonomy object.
       
   172 	 * @param string      $search          The search term.
       
   173 	 */
       
   174 	$results = apply_filters( 'ajax_term_search_results', $results, $taxonomy_object, $search );
       
   175 
   165 	echo implode( "\n", $results );
   176 	echo implode( "\n", $results );
   166 	wp_die();
   177 	wp_die();
   167 }
   178 }
   168 
   179 
   169 /**
   180 /**
   170  * Ajax handler for compression testing.
   181  * Handles compression testing via AJAX.
   171  *
   182  *
   172  * @since 3.1.0
   183  * @since 3.1.0
   173  */
   184  */
   174 function wp_ajax_wp_compression_test() {
   185 function wp_ajax_wp_compression_test() {
   175 	if ( ! current_user_can( 'manage_options' ) ) {
   186 	if ( ! current_user_can( 'manage_options' ) ) {
   176 		wp_die( -1 );
   187 		wp_die( -1 );
   177 	}
   188 	}
   178 
   189 
   179 	if ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ) {
   190 	if ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ) {
   180 		update_site_option( 'can_compress_scripts', 0 );
   191 		// Use `update_option()` on single site to mark the option for autoloading.
       
   192 		if ( is_multisite() ) {
       
   193 			update_site_option( 'can_compress_scripts', 0 );
       
   194 		} else {
       
   195 			update_option( 'can_compress_scripts', 0, true );
       
   196 		}
   181 		wp_die( 0 );
   197 		wp_die( 0 );
   182 	}
   198 	}
   183 
   199 
   184 	if ( isset( $_GET['test'] ) ) {
   200 	if ( isset( $_GET['test'] ) ) {
   185 		header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
   201 		header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
   187 		header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
   203 		header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
   188 		header( 'Content-Type: application/javascript; charset=UTF-8' );
   204 		header( 'Content-Type: application/javascript; charset=UTF-8' );
   189 		$force_gzip = ( defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP );
   205 		$force_gzip = ( defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP );
   190 		$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."';
   206 		$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."';
   191 
   207 
   192 		if ( 1 == $_GET['test'] ) {
   208 		if ( '1' === $_GET['test'] ) {
   193 			echo $test_str;
   209 			echo $test_str;
   194 			wp_die();
   210 			wp_die();
   195 		} elseif ( 2 == $_GET['test'] ) {
   211 		} elseif ( '2' === $_GET['test'] ) {
   196 			if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
   212 			if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
   197 				wp_die( -1 );
   213 				wp_die( -1 );
   198 			}
   214 			}
   199 
   215 
   200 			if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate' ) && function_exists( 'gzdeflate' ) && ! $force_gzip ) {
   216 			if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate' ) && function_exists( 'gzdeflate' ) && ! $force_gzip ) {
   209 
   225 
   210 			echo $out;
   226 			echo $out;
   211 			wp_die();
   227 			wp_die();
   212 		} elseif ( 'no' === $_GET['test'] ) {
   228 		} elseif ( 'no' === $_GET['test'] ) {
   213 			check_ajax_referer( 'update_can_compress_scripts' );
   229 			check_ajax_referer( 'update_can_compress_scripts' );
   214 			update_site_option( 'can_compress_scripts', 0 );
   230 			// Use `update_option()` on single site to mark the option for autoloading.
       
   231 			if ( is_multisite() ) {
       
   232 				update_site_option( 'can_compress_scripts', 0 );
       
   233 			} else {
       
   234 				update_option( 'can_compress_scripts', 0, true );
       
   235 			}
   215 		} elseif ( 'yes' === $_GET['test'] ) {
   236 		} elseif ( 'yes' === $_GET['test'] ) {
   216 			check_ajax_referer( 'update_can_compress_scripts' );
   237 			check_ajax_referer( 'update_can_compress_scripts' );
   217 			update_site_option( 'can_compress_scripts', 1 );
   238 			// Use `update_option()` on single site to mark the option for autoloading.
       
   239 			if ( is_multisite() ) {
       
   240 				update_site_option( 'can_compress_scripts', 1 );
       
   241 			} else {
       
   242 				update_option( 'can_compress_scripts', 1, true );
       
   243 			}
   218 		}
   244 		}
   219 	}
   245 	}
   220 
   246 
   221 	wp_die( 0 );
   247 	wp_die( 0 );
   222 }
   248 }
   223 
   249 
   224 /**
   250 /**
   225  * Ajax handler for image editor previews.
   251  * Handles image editor previews via AJAX.
   226  *
   252  *
   227  * @since 3.1.0
   253  * @since 3.1.0
   228  */
   254  */
   229 function wp_ajax_imgedit_preview() {
   255 function wp_ajax_imgedit_preview() {
   230 	$post_id = (int) $_GET['postid'];
   256 	$post_id = (int) $_GET['postid'];
   232 		wp_die( -1 );
   258 		wp_die( -1 );
   233 	}
   259 	}
   234 
   260 
   235 	check_ajax_referer( "image_editor-$post_id" );
   261 	check_ajax_referer( "image_editor-$post_id" );
   236 
   262 
   237 	include_once ABSPATH . 'wp-admin/includes/image-edit.php';
   263 	require_once ABSPATH . 'wp-admin/includes/image-edit.php';
   238 
   264 
   239 	if ( ! stream_preview_image( $post_id ) ) {
   265 	if ( ! stream_preview_image( $post_id ) ) {
   240 		wp_die( -1 );
   266 		wp_die( -1 );
   241 	}
   267 	}
   242 
   268 
   243 	wp_die();
   269 	wp_die();
   244 }
   270 }
   245 
   271 
   246 /**
   272 /**
   247  * Ajax handler for oEmbed caching.
   273  * Handles oEmbed caching via AJAX.
   248  *
   274  *
   249  * @since 3.1.0
   275  * @since 3.1.0
   250  *
   276  *
   251  * @global WP_Embed $wp_embed
   277  * @global WP_Embed $wp_embed WordPress Embed object.
   252  */
   278  */
   253 function wp_ajax_oembed_cache() {
   279 function wp_ajax_oembed_cache() {
   254 	$GLOBALS['wp_embed']->cache_oembed( $_GET['post'] );
   280 	$GLOBALS['wp_embed']->cache_oembed( $_GET['post'] );
   255 	wp_die( 0 );
   281 	wp_die( 0 );
   256 }
   282 }
   257 
   283 
   258 /**
   284 /**
   259  * Ajax handler for user autocomplete.
   285  * Handles user autocomplete via AJAX.
   260  *
   286  *
   261  * @since 3.4.0
   287  * @since 3.4.0
   262  */
   288  */
   263 function wp_ajax_autocomplete_user() {
   289 function wp_ajax_autocomplete_user() {
   264 	if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) {
   290 	if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) {
   270 		wp_die( -1 );
   296 		wp_die( -1 );
   271 	}
   297 	}
   272 
   298 
   273 	$return = array();
   299 	$return = array();
   274 
   300 
   275 	// Check the type of request.
   301 	/*
   276 	// Current allowed values are `add` and `search`.
   302 	 * Check the type of request.
       
   303 	 * Current allowed values are `add` and `search`.
       
   304 	 */
   277 	if ( isset( $_REQUEST['autocomplete_type'] ) && 'search' === $_REQUEST['autocomplete_type'] ) {
   305 	if ( isset( $_REQUEST['autocomplete_type'] ) && 'search' === $_REQUEST['autocomplete_type'] ) {
   278 		$type = $_REQUEST['autocomplete_type'];
   306 		$type = $_REQUEST['autocomplete_type'];
   279 	} else {
   307 	} else {
   280 		$type = 'add';
   308 		$type = 'add';
   281 	}
   309 	}
   282 
   310 
   283 	// Check the desired field for value.
   311 	/*
   284 	// Current allowed values are `user_email` and `user_login`.
   312 	 * Check the desired field for value.
       
   313 	 * Current allowed values are `user_email` and `user_login`.
       
   314 	 */
   285 	if ( isset( $_REQUEST['autocomplete_field'] ) && 'user_email' === $_REQUEST['autocomplete_field'] ) {
   315 	if ( isset( $_REQUEST['autocomplete_field'] ) && 'user_email' === $_REQUEST['autocomplete_field'] ) {
   286 		$field = $_REQUEST['autocomplete_field'];
   316 		$field = $_REQUEST['autocomplete_field'];
   287 	} else {
   317 	} else {
   288 		$field = 'user_login';
   318 		$field = 'user_login';
   289 	}
   319 	}
   381 		wp_send_json_success( $events );
   411 		wp_send_json_success( $events );
   382 	}
   412 	}
   383 }
   413 }
   384 
   414 
   385 /**
   415 /**
   386  * Ajax handler for dashboard widgets.
   416  * Handles dashboard widgets via AJAX.
   387  *
   417  *
   388  * @since 3.4.0
   418  * @since 3.4.0
   389  */
   419  */
   390 function wp_ajax_dashboard_widgets() {
   420 function wp_ajax_dashboard_widgets() {
   391 	require_once ABSPATH . 'wp-admin/includes/dashboard.php';
   421 	require_once ABSPATH . 'wp-admin/includes/dashboard.php';
   402 	}
   432 	}
   403 	wp_die();
   433 	wp_die();
   404 }
   434 }
   405 
   435 
   406 /**
   436 /**
   407  * Ajax handler for Customizer preview logged-in status.
   437  * Handles Customizer preview logged-in status via AJAX.
   408  *
   438  *
   409  * @since 3.4.0
   439  * @since 3.4.0
   410  */
   440  */
   411 function wp_ajax_logged_in() {
   441 function wp_ajax_logged_in() {
   412 	wp_die( 1 );
   442 	wp_die( 1 );
   429  */
   459  */
   430 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
   460 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
   431 	$total    = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0;
   461 	$total    = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0;
   432 	$per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
   462 	$per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
   433 	$page     = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0;
   463 	$page     = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0;
   434 	$url      = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : '';
   464 	$url      = isset( $_POST['_url'] ) ? sanitize_url( $_POST['_url'] ) : '';
   435 
   465 
   436 	// JS didn't send us everything we need to know. Just die with success message.
   466 	// JS didn't send us everything we need to know. Just die with success message.
   437 	if ( ! $total || ! $per_page || ! $page || ! $url ) {
   467 	if ( ! $total || ! $per_page || ! $page || ! $url ) {
   438 		$time           = time();
   468 		$time           = time();
   439 		$comment        = get_comment( $comment_id );
   469 		$comment        = get_comment( $comment_id );
   481 	if ( $total < 0 ) {
   511 	if ( $total < 0 ) {
   482 		$total = 0;
   512 		$total = 0;
   483 	}
   513 	}
   484 
   514 
   485 	// Only do the expensive stuff on a page-break, and about 1 other time per page.
   515 	// Only do the expensive stuff on a page-break, and about 1 other time per page.
   486 	if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
   516 	if ( 0 === $total % $per_page || 1 === mt_rand( 1, $per_page ) ) {
   487 		$post_id = 0;
   517 		$post_id = 0;
   488 		// What type of comment count are we looking for?
   518 		// What type of comment count are we looking for?
   489 		$status = 'all';
   519 		$status = 'all';
   490 		$parsed = parse_url( $url );
   520 		$parsed = parse_url( $url );
   491 
   521 
   529 			'supplemental' => array(
   559 			'supplemental' => array(
   530 				'status'               => $comment ? $comment->comment_approved : '',
   560 				'status'               => $comment ? $comment->comment_approved : '',
   531 				'postId'               => $comment ? $comment->comment_post_ID : '',
   561 				'postId'               => $comment ? $comment->comment_post_ID : '',
   532 				/* translators: %s: Number of comments. */
   562 				/* translators: %s: Number of comments. */
   533 				'total_items_i18n'     => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ),
   563 				'total_items_i18n'     => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ),
   534 				'total_pages'          => ceil( $total / $per_page ),
   564 				'total_pages'          => (int) ceil( $total / $per_page ),
   535 				'total_pages_i18n'     => number_format_i18n( ceil( $total / $per_page ) ),
   565 				'total_pages_i18n'     => number_format_i18n( (int) ceil( $total / $per_page ) ),
   536 				'total'                => $total,
   566 				'total'                => $total,
   537 				'time'                 => $time,
   567 				'time'                 => $time,
   538 				'in_moderation'        => $counts->moderated,
   568 				'in_moderation'        => $counts->moderated,
   539 				'i18n_moderation_text' => sprintf(
   569 				'i18n_moderation_text' => sprintf(
   540 					/* translators: %s: Number of comments. */
   570 					/* translators: %s: Number of comments. */
   550 //
   580 //
   551 // POST-based Ajax handlers.
   581 // POST-based Ajax handlers.
   552 //
   582 //
   553 
   583 
   554 /**
   584 /**
   555  * Ajax handler for adding a hierarchical term.
   585  * Handles adding a hierarchical term via AJAX.
   556  *
   586  *
   557  * @since 3.1.0
   587  * @since 3.1.0
   558  * @access private
   588  * @access private
   559  */
   589  */
   560 function _wp_ajax_add_hierarchical_term() {
   590 function _wp_ajax_add_hierarchical_term() {
   680 	$x = new WP_Ajax_Response( $add );
   710 	$x = new WP_Ajax_Response( $add );
   681 	$x->send();
   711 	$x->send();
   682 }
   712 }
   683 
   713 
   684 /**
   714 /**
   685  * Ajax handler for deleting a comment.
   715  * Handles deleting a comment via AJAX.
   686  *
   716  *
   687  * @since 3.1.0
   717  * @since 3.1.0
   688  */
   718  */
   689 function wp_ajax_delete_comment() {
   719 function wp_ajax_delete_comment() {
   690 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   720 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   701 
   731 
   702 	check_ajax_referer( "delete-comment_$id" );
   732 	check_ajax_referer( "delete-comment_$id" );
   703 	$status = wp_get_comment_status( $comment );
   733 	$status = wp_get_comment_status( $comment );
   704 	$delta  = -1;
   734 	$delta  = -1;
   705 
   735 
   706 	if ( isset( $_POST['trash'] ) && 1 == $_POST['trash'] ) {
   736 	if ( isset( $_POST['trash'] ) && '1' === $_POST['trash'] ) {
   707 		if ( 'trash' === $status ) {
   737 		if ( 'trash' === $status ) {
   708 			wp_die( time() );
   738 			wp_die( time() );
   709 		}
   739 		}
   710 
   740 
   711 		$r = wp_trash_comment( $comment );
   741 		$r = wp_trash_comment( $comment );
   712 	} elseif ( isset( $_POST['untrash'] ) && 1 == $_POST['untrash'] ) {
   742 	} elseif ( isset( $_POST['untrash'] ) && '1' === $_POST['untrash'] ) {
   713 		if ( 'trash' !== $status ) {
   743 		if ( 'trash' !== $status ) {
   714 			wp_die( time() );
   744 			wp_die( time() );
   715 		}
   745 		}
   716 
   746 
   717 		$r = wp_untrash_comment( $comment );
   747 		$r = wp_untrash_comment( $comment );
   718 
   748 
   719 		// Undo trash, not in Trash.
   749 		// Undo trash, not in Trash.
   720 		if ( ! isset( $_POST['comment_status'] ) || 'trash' !== $_POST['comment_status'] ) {
   750 		if ( ! isset( $_POST['comment_status'] ) || 'trash' !== $_POST['comment_status'] ) {
   721 			$delta = 1;
   751 			$delta = 1;
   722 		}
   752 		}
   723 	} elseif ( isset( $_POST['spam'] ) && 1 == $_POST['spam'] ) {
   753 	} elseif ( isset( $_POST['spam'] ) && '1' === $_POST['spam'] ) {
   724 		if ( 'spam' === $status ) {
   754 		if ( 'spam' === $status ) {
   725 			wp_die( time() );
   755 			wp_die( time() );
   726 		}
   756 		}
   727 
   757 
   728 		$r = wp_spam_comment( $comment );
   758 		$r = wp_spam_comment( $comment );
   729 	} elseif ( isset( $_POST['unspam'] ) && 1 == $_POST['unspam'] ) {
   759 	} elseif ( isset( $_POST['unspam'] ) && '1' === $_POST['unspam'] ) {
   730 		if ( 'spam' !== $status ) {
   760 		if ( 'spam' !== $status ) {
   731 			wp_die( time() );
   761 			wp_die( time() );
   732 		}
   762 		}
   733 
   763 
   734 		$r = wp_unspam_comment( $comment );
   764 		$r = wp_unspam_comment( $comment );
   735 
   765 
   736 		// Undo spam, not in spam.
   766 		// Undo spam, not in spam.
   737 		if ( ! isset( $_POST['comment_status'] ) || 'spam' !== $_POST['comment_status'] ) {
   767 		if ( ! isset( $_POST['comment_status'] ) || 'spam' !== $_POST['comment_status'] ) {
   738 			$delta = 1;
   768 			$delta = 1;
   739 		}
   769 		}
   740 	} elseif ( isset( $_POST['delete'] ) && 1 == $_POST['delete'] ) {
   770 	} elseif ( isset( $_POST['delete'] ) && '1' === $_POST['delete'] ) {
   741 		$r = wp_delete_comment( $comment );
   771 		$r = wp_delete_comment( $comment );
   742 	} else {
   772 	} else {
   743 		wp_die( -1 );
   773 		wp_die( -1 );
   744 	}
   774 	}
   745 
   775 
   750 
   780 
   751 	wp_die( 0 );
   781 	wp_die( 0 );
   752 }
   782 }
   753 
   783 
   754 /**
   784 /**
   755  * Ajax handler for deleting a tag.
   785  * Handles deleting a tag via AJAX.
   756  *
   786  *
   757  * @since 3.1.0
   787  * @since 3.1.0
   758  */
   788  */
   759 function wp_ajax_delete_tag() {
   789 function wp_ajax_delete_tag() {
   760 	$tag_id = (int) $_POST['tag_ID'];
   790 	$tag_id = (int) $_POST['tag_ID'];
   777 		wp_die( 0 );
   807 		wp_die( 0 );
   778 	}
   808 	}
   779 }
   809 }
   780 
   810 
   781 /**
   811 /**
   782  * Ajax handler for deleting a link.
   812  * Handles deleting a link via AJAX.
   783  *
   813  *
   784  * @since 3.1.0
   814  * @since 3.1.0
   785  */
   815  */
   786 function wp_ajax_delete_link() {
   816 function wp_ajax_delete_link() {
   787 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   817 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   803 		wp_die( 0 );
   833 		wp_die( 0 );
   804 	}
   834 	}
   805 }
   835 }
   806 
   836 
   807 /**
   837 /**
   808  * Ajax handler for deleting meta.
   838  * Handles deleting meta via AJAX.
   809  *
   839  *
   810  * @since 3.1.0
   840  * @since 3.1.0
   811  */
   841  */
   812 function wp_ajax_delete_meta() {
   842 function wp_ajax_delete_meta() {
   813 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   843 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   829 
   859 
   830 	wp_die( 0 );
   860 	wp_die( 0 );
   831 }
   861 }
   832 
   862 
   833 /**
   863 /**
   834  * Ajax handler for deleting a post.
   864  * Handles deleting a post via AJAX.
   835  *
   865  *
   836  * @since 3.1.0
   866  * @since 3.1.0
   837  *
   867  *
   838  * @param string $action Action to perform.
   868  * @param string $action Action to perform.
   839  */
   869  */
   859 		wp_die( 0 );
   889 		wp_die( 0 );
   860 	}
   890 	}
   861 }
   891 }
   862 
   892 
   863 /**
   893 /**
   864  * Ajax handler for sending a post to the Trash.
   894  * Handles sending a post to the Trash via AJAX.
   865  *
   895  *
   866  * @since 3.1.0
   896  * @since 3.1.0
   867  *
   897  *
   868  * @param string $action Action to perform.
   898  * @param string $action Action to perform.
   869  */
   899  */
   895 
   925 
   896 	wp_die( 0 );
   926 	wp_die( 0 );
   897 }
   927 }
   898 
   928 
   899 /**
   929 /**
   900  * Ajax handler to restore a post from the Trash.
   930  * Handles restoring a post from the Trash via AJAX.
   901  *
   931  *
   902  * @since 3.1.0
   932  * @since 3.1.0
   903  *
   933  *
   904  * @param string $action Action to perform.
   934  * @param string $action Action to perform.
   905  */
   935  */
   910 
   940 
   911 	wp_ajax_trash_post( $action );
   941 	wp_ajax_trash_post( $action );
   912 }
   942 }
   913 
   943 
   914 /**
   944 /**
   915  * Ajax handler to delete a page.
   945  * Handles deleting a page via AJAX.
   916  *
   946  *
   917  * @since 3.1.0
   947  * @since 3.1.0
   918  *
   948  *
   919  * @param string $action Action to perform.
   949  * @param string $action Action to perform.
   920  */
   950  */
   940 		wp_die( 0 );
   970 		wp_die( 0 );
   941 	}
   971 	}
   942 }
   972 }
   943 
   973 
   944 /**
   974 /**
   945  * Ajax handler to dim a comment.
   975  * Handles dimming a comment via AJAX.
   946  *
   976  *
   947  * @since 3.1.0
   977  * @since 3.1.0
   948  */
   978  */
   949 function wp_ajax_dim_comment() {
   979 function wp_ajax_dim_comment() {
   950 	$id      = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   980 	$id      = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   968 		wp_die( -1 );
   998 		wp_die( -1 );
   969 	}
   999 	}
   970 
  1000 
   971 	$current = wp_get_comment_status( $comment );
  1001 	$current = wp_get_comment_status( $comment );
   972 
  1002 
   973 	if ( isset( $_POST['new'] ) && $_POST['new'] == $current ) {
  1003 	if ( isset( $_POST['new'] ) && $_POST['new'] === $current ) {
   974 		wp_die( time() );
  1004 		wp_die( time() );
   975 	}
  1005 	}
   976 
  1006 
   977 	check_ajax_referer( "approve-comment_$id" );
  1007 	check_ajax_referer( "approve-comment_$id" );
   978 
  1008 
   996 	_wp_ajax_delete_comment_response( $comment->comment_ID );
  1026 	_wp_ajax_delete_comment_response( $comment->comment_ID );
   997 	wp_die( 0 );
  1027 	wp_die( 0 );
   998 }
  1028 }
   999 
  1029 
  1000 /**
  1030 /**
  1001  * Ajax handler for adding a link category.
  1031  * Handles adding a link category via AJAX.
  1002  *
  1032  *
  1003  * @since 3.1.0
  1033  * @since 3.1.0
  1004  *
  1034  *
  1005  * @param string $action Action to perform.
  1035  * @param string $action Action to perform.
  1006  */
  1036  */
  1008 	if ( empty( $action ) ) {
  1038 	if ( empty( $action ) ) {
  1009 		$action = 'add-link-category';
  1039 		$action = 'add-link-category';
  1010 	}
  1040 	}
  1011 
  1041 
  1012 	check_ajax_referer( $action );
  1042 	check_ajax_referer( $action );
  1013 	$tax = get_taxonomy( 'link_category' );
  1043 
  1014 
  1044 	$taxonomy_object = get_taxonomy( 'link_category' );
  1015 	if ( ! current_user_can( $tax->cap->manage_terms ) ) {
  1045 
       
  1046 	if ( ! current_user_can( $taxonomy_object->cap->manage_terms ) ) {
  1016 		wp_die( -1 );
  1047 		wp_die( -1 );
  1017 	}
  1048 	}
  1018 
  1049 
  1019 	$names = explode( ',', wp_unslash( $_POST['newcat'] ) );
  1050 	$names = explode( ',', wp_unslash( $_POST['newcat'] ) );
  1020 	$x     = new WP_Ajax_Response();
  1051 	$x     = new WP_Ajax_Response();
  1048 	}
  1079 	}
  1049 	$x->send();
  1080 	$x->send();
  1050 }
  1081 }
  1051 
  1082 
  1052 /**
  1083 /**
  1053  * Ajax handler to add a tag.
  1084  * Handles adding a tag via AJAX.
  1054  *
  1085  *
  1055  * @since 3.1.0
  1086  * @since 3.1.0
  1056  */
  1087  */
  1057 function wp_ajax_add_tag() {
  1088 function wp_ajax_add_tag() {
  1058 	check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
  1089 	check_ajax_referer( 'add-tag', '_wpnonce_add-tag' );
  1059 	$taxonomy = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
  1090 
  1060 	$tax      = get_taxonomy( $taxonomy );
  1091 	$taxonomy        = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
  1061 
  1092 	$taxonomy_object = get_taxonomy( $taxonomy );
  1062 	if ( ! current_user_can( $tax->cap->edit_terms ) ) {
  1093 
       
  1094 	if ( ! current_user_can( $taxonomy_object->cap->edit_terms ) ) {
  1063 		wp_die( -1 );
  1095 		wp_die( -1 );
  1064 	}
  1096 	}
  1065 
  1097 
  1066 	$x = new WP_Ajax_Response();
  1098 	$x = new WP_Ajax_Response();
  1067 
  1099 
  1109 	$parents = ob_get_clean();
  1141 	$parents = ob_get_clean();
  1110 
  1142 
  1111 	require ABSPATH . 'wp-admin/includes/edit-tag-messages.php';
  1143 	require ABSPATH . 'wp-admin/includes/edit-tag-messages.php';
  1112 
  1144 
  1113 	$message = '';
  1145 	$message = '';
  1114 	if ( isset( $messages[ $tax->name ][1] ) ) {
  1146 	if ( isset( $messages[ $taxonomy_object->name ][1] ) ) {
  1115 		$message = $messages[ $tax->name ][1];
  1147 		$message = $messages[ $taxonomy_object->name ][1];
  1116 	} elseif ( isset( $messages['_item'][1] ) ) {
  1148 	} elseif ( isset( $messages['_item'][1] ) ) {
  1117 		$message = $messages['_item'][1];
  1149 		$message = $messages['_item'][1];
  1118 	}
  1150 	}
  1119 
  1151 
  1120 	$x->add(
  1152 	$x->add(
  1139 
  1171 
  1140 	$x->send();
  1172 	$x->send();
  1141 }
  1173 }
  1142 
  1174 
  1143 /**
  1175 /**
  1144  * Ajax handler for getting a tagcloud.
  1176  * Handles getting a tagcloud via AJAX.
  1145  *
  1177  *
  1146  * @since 3.1.0
  1178  * @since 3.1.0
  1147  */
  1179  */
  1148 function wp_ajax_get_tagcloud() {
  1180 function wp_ajax_get_tagcloud() {
  1149 	if ( ! isset( $_POST['tax'] ) ) {
  1181 	if ( ! isset( $_POST['tax'] ) ) {
  1150 		wp_die( 0 );
  1182 		wp_die( 0 );
  1151 	}
  1183 	}
  1152 
  1184 
  1153 	$taxonomy = sanitize_key( $_POST['tax'] );
  1185 	$taxonomy        = sanitize_key( $_POST['tax'] );
  1154 	$tax      = get_taxonomy( $taxonomy );
  1186 	$taxonomy_object = get_taxonomy( $taxonomy );
  1155 
  1187 
  1156 	if ( ! $tax ) {
  1188 	if ( ! $taxonomy_object ) {
  1157 		wp_die( 0 );
  1189 		wp_die( 0 );
  1158 	}
  1190 	}
  1159 
  1191 
  1160 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
  1192 	if ( ! current_user_can( $taxonomy_object->cap->assign_terms ) ) {
  1161 		wp_die( -1 );
  1193 		wp_die( -1 );
  1162 	}
  1194 	}
  1163 
  1195 
  1164 	$tags = get_terms(
  1196 	$tags = get_terms(
  1165 		array(
  1197 		array(
  1169 			'order'    => 'DESC',
  1201 			'order'    => 'DESC',
  1170 		)
  1202 		)
  1171 	);
  1203 	);
  1172 
  1204 
  1173 	if ( empty( $tags ) ) {
  1205 	if ( empty( $tags ) ) {
  1174 		wp_die( $tax->labels->not_found );
  1206 		wp_die( $taxonomy_object->labels->not_found );
  1175 	}
  1207 	}
  1176 
  1208 
  1177 	if ( is_wp_error( $tags ) ) {
  1209 	if ( is_wp_error( $tags ) ) {
  1178 		wp_die( $tags->get_error_message() );
  1210 		wp_die( $tags->get_error_message() );
  1179 	}
  1211 	}
  1199 	echo $return;
  1231 	echo $return;
  1200 	wp_die();
  1232 	wp_die();
  1201 }
  1233 }
  1202 
  1234 
  1203 /**
  1235 /**
  1204  * Ajax handler for getting comments.
  1236  * Handles getting comments via AJAX.
  1205  *
  1237  *
  1206  * @since 3.1.0
  1238  * @since 3.1.0
  1207  *
  1239  *
  1208  * @global int $post_id
  1240  * @global int $post_id
  1209  *
  1241  *
  1262 
  1294 
  1263 	$x->send();
  1295 	$x->send();
  1264 }
  1296 }
  1265 
  1297 
  1266 /**
  1298 /**
  1267  * Ajax handler for replying to a comment.
  1299  * Handles replying to a comment via AJAX.
  1268  *
  1300  *
  1269  * @since 3.1.0
  1301  * @since 3.1.0
  1270  *
  1302  *
  1271  * @param string $action Action to perform.
  1303  * @param string $action Action to perform.
  1272  */
  1304  */
  1275 		$action = 'replyto-comment';
  1307 		$action = 'replyto-comment';
  1276 	}
  1308 	}
  1277 
  1309 
  1278 	check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
  1310 	check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
  1279 
  1311 
  1280 	$comment_post_ID = (int) $_POST['comment_post_ID'];
  1312 	$comment_post_id = (int) $_POST['comment_post_ID'];
  1281 	$post            = get_post( $comment_post_ID );
  1313 	$post            = get_post( $comment_post_id );
  1282 
  1314 
  1283 	if ( ! $post ) {
  1315 	if ( ! $post ) {
  1284 		wp_die( -1 );
  1316 		wp_die( -1 );
  1285 	}
  1317 	}
  1286 
  1318 
  1287 	if ( ! current_user_can( 'edit_post', $comment_post_ID ) ) {
  1319 	if ( ! current_user_can( 'edit_post', $comment_post_id ) ) {
  1288 		wp_die( -1 );
  1320 		wp_die( -1 );
  1289 	}
  1321 	}
  1290 
  1322 
  1291 	if ( empty( $post->post_status ) ) {
  1323 	if ( empty( $post->post_status ) ) {
  1292 		wp_die( 1 );
  1324 		wp_die( 1 );
  1295 	}
  1327 	}
  1296 
  1328 
  1297 	$user = wp_get_current_user();
  1329 	$user = wp_get_current_user();
  1298 
  1330 
  1299 	if ( $user->exists() ) {
  1331 	if ( $user->exists() ) {
  1300 		$user_ID              = $user->ID;
       
  1301 		$comment_author       = wp_slash( $user->display_name );
  1332 		$comment_author       = wp_slash( $user->display_name );
  1302 		$comment_author_email = wp_slash( $user->user_email );
  1333 		$comment_author_email = wp_slash( $user->user_email );
  1303 		$comment_author_url   = wp_slash( $user->user_url );
  1334 		$comment_author_url   = wp_slash( $user->user_url );
  1304 		$comment_content      = trim( $_POST['content'] );
  1335 		$user_id              = $user->ID;
  1305 		$comment_type         = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : 'comment';
       
  1306 
  1336 
  1307 		if ( current_user_can( 'unfiltered_html' ) ) {
  1337 		if ( current_user_can( 'unfiltered_html' ) ) {
  1308 			if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) ) {
  1338 			if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) ) {
  1309 				$_POST['_wp_unfiltered_html_comment'] = '';
  1339 				$_POST['_wp_unfiltered_html_comment'] = '';
  1310 			}
  1340 			}
  1311 
  1341 
  1312 			if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
  1342 			if ( wp_create_nonce( 'unfiltered-html-comment' ) !== $_POST['_wp_unfiltered_html_comment'] ) {
  1313 				kses_remove_filters(); // Start with a clean slate.
  1343 				kses_remove_filters(); // Start with a clean slate.
  1314 				kses_init_filters();   // Set up the filters.
  1344 				kses_init_filters();   // Set up the filters.
  1315 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  1345 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  1316 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  1346 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  1317 			}
  1347 			}
  1318 		}
  1348 		}
  1319 	} else {
  1349 	} else {
  1320 		wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
  1350 		wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
  1321 	}
  1351 	}
  1322 
  1352 
       
  1353 	$comment_content = trim( $_POST['content'] );
       
  1354 
  1323 	if ( '' === $comment_content ) {
  1355 	if ( '' === $comment_content ) {
  1324 		wp_die( __( 'Please type your comment text.' ) );
  1356 		wp_die( __( 'Please type your comment text.' ) );
  1325 	}
  1357 	}
  1326 
  1358 
       
  1359 	$comment_type = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : 'comment';
       
  1360 
  1327 	$comment_parent = 0;
  1361 	$comment_parent = 0;
  1328 
  1362 
  1329 	if ( isset( $_POST['comment_ID'] ) ) {
  1363 	if ( isset( $_POST['comment_ID'] ) ) {
  1330 		$comment_parent = absint( $_POST['comment_ID'] );
  1364 		$comment_parent = absint( $_POST['comment_ID'] );
  1331 	}
  1365 	}
  1332 
  1366 
  1333 	$comment_auto_approved = false;
  1367 	$comment_auto_approved = false;
  1334 	$commentdata           = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID' );
  1368 
       
  1369 	$commentdata = array(
       
  1370 		'comment_post_ID' => $comment_post_id,
       
  1371 	);
       
  1372 
       
  1373 	$commentdata += compact(
       
  1374 		'comment_author',
       
  1375 		'comment_author_email',
       
  1376 		'comment_author_url',
       
  1377 		'comment_content',
       
  1378 		'comment_type',
       
  1379 		'comment_parent',
       
  1380 		'user_id'
       
  1381 	);
  1335 
  1382 
  1336 	// Automatically approve parent comment.
  1383 	// Automatically approve parent comment.
  1337 	if ( ! empty( $_POST['approve_parent'] ) ) {
  1384 	if ( ! empty( $_POST['approve_parent'] ) ) {
  1338 		$parent = get_comment( $comment_parent );
  1385 		$parent = get_comment( $comment_parent );
  1339 
  1386 
  1340 		if ( $parent && '0' === $parent->comment_approved && $parent->comment_post_ID == $comment_post_ID ) {
  1387 		if ( $parent && '0' === $parent->comment_approved && (int) $parent->comment_post_ID === $comment_post_id ) {
  1341 			if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) {
  1388 			if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) {
  1342 				wp_die( -1 );
  1389 				wp_die( -1 );
  1343 			}
  1390 			}
  1344 
  1391 
  1345 			if ( wp_set_comment_status( $parent, 'approve' ) ) {
  1392 			if ( wp_set_comment_status( $parent, 'approve' ) ) {
  1407 	$x->add( $response );
  1454 	$x->add( $response );
  1408 	$x->send();
  1455 	$x->send();
  1409 }
  1456 }
  1410 
  1457 
  1411 /**
  1458 /**
  1412  * Ajax handler for editing a comment.
  1459  * Handles editing a comment via AJAX.
  1413  *
  1460  *
  1414  * @since 3.1.0
  1461  * @since 3.1.0
  1415  */
  1462  */
  1416 function wp_ajax_edit_comment() {
  1463 function wp_ajax_edit_comment() {
  1417 	check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
  1464 	check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
  1433 	$updated = edit_comment();
  1480 	$updated = edit_comment();
  1434 	if ( is_wp_error( $updated ) ) {
  1481 	if ( is_wp_error( $updated ) ) {
  1435 		wp_die( $updated->get_error_message() );
  1482 		wp_die( $updated->get_error_message() );
  1436 	}
  1483 	}
  1437 
  1484 
  1438 	$position      = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1485 	$position = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1439 	$checkbox      = ( isset( $_POST['checkbox'] ) && true == $_POST['checkbox'] ) ? 1 : 0;
  1486 	/*
       
  1487 	 * Checkbox is used to differentiate between the Edit Comments screen (1)
       
  1488 	 * and the Comments section on the Edit Post screen (0).
       
  1489 	 */
       
  1490 	$checkbox      = ( isset( $_POST['checkbox'] ) && '1' === $_POST['checkbox'] ) ? 1 : 0;
  1440 	$wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1491 	$wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1441 
  1492 
  1442 	$comment = get_comment( $comment_id );
  1493 	$comment = get_comment( $comment_id );
  1443 
  1494 
  1444 	if ( empty( $comment->comment_ID ) ) {
  1495 	if ( empty( $comment->comment_ID ) ) {
  1462 
  1513 
  1463 	$x->send();
  1514 	$x->send();
  1464 }
  1515 }
  1465 
  1516 
  1466 /**
  1517 /**
  1467  * Ajax handler for adding a menu item.
  1518  * Handles adding a menu item via AJAX.
  1468  *
  1519  *
  1469  * @since 3.1.0
  1520  * @since 3.1.0
  1470  */
  1521  */
  1471 function wp_ajax_add_menu_item() {
  1522 function wp_ajax_add_menu_item() {
  1472 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
  1523 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
  1475 		wp_die( -1 );
  1526 		wp_die( -1 );
  1476 	}
  1527 	}
  1477 
  1528 
  1478 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1529 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1479 
  1530 
  1480 	// For performance reasons, we omit some object properties from the checklist.
  1531 	/*
  1481 	// The following is a hacky way to restore them when adding non-custom items.
  1532 	 * For performance reasons, we omit some object properties from the checklist.
       
  1533 	 * The following is a hacky way to restore them when adding non-custom items.
       
  1534 	 */
  1482 	$menu_items_data = array();
  1535 	$menu_items_data = array();
  1483 
  1536 
  1484 	foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
  1537 	foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
  1485 		if (
  1538 		if (
  1486 			! empty( $menu_item_data['menu-item-type'] ) &&
  1539 			! empty( $menu_item_data['menu-item-type'] ) &&
  1540 		$args = array(
  1593 		$args = array(
  1541 			'after'       => '',
  1594 			'after'       => '',
  1542 			'before'      => '',
  1595 			'before'      => '',
  1543 			'link_after'  => '',
  1596 			'link_after'  => '',
  1544 			'link_before' => '',
  1597 			'link_before' => '',
  1545 			'walker'      => new $walker_class_name,
  1598 			'walker'      => new $walker_class_name(),
  1546 		);
  1599 		);
  1547 
  1600 
  1548 		echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
  1601 		echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
  1549 	}
  1602 	}
  1550 
  1603 
  1551 	wp_die();
  1604 	wp_die();
  1552 }
  1605 }
  1553 
  1606 
  1554 /**
  1607 /**
  1555  * Ajax handler for adding meta.
  1608  * Handles adding meta via AJAX.
  1556  *
  1609  *
  1557  * @since 3.1.0
  1610  * @since 3.1.0
  1558  */
  1611  */
  1559 function wp_ajax_add_meta() {
  1612 function wp_ajax_add_meta() {
  1560 	check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
  1613 	check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
  1577 			$post_data['action']      = 'draft'; // Warning fix.
  1630 			$post_data['action']      = 'draft'; // Warning fix.
  1578 			$post_data['post_ID']     = $pid;
  1631 			$post_data['post_ID']     = $pid;
  1579 			$post_data['post_type']   = $post->post_type;
  1632 			$post_data['post_type']   = $post->post_type;
  1580 			$post_data['post_status'] = 'draft';
  1633 			$post_data['post_status'] = 'draft';
  1581 			$now                      = time();
  1634 			$now                      = time();
  1582 			/* translators: 1: Post creation date, 2: Post creation time. */
  1635 
  1583 			$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), gmdate( __( 'F j, Y' ), $now ), gmdate( __( 'g:i a' ), $now ) );
  1636 			$post_data['post_title'] = sprintf(
       
  1637 				/* translators: 1: Post creation date, 2: Post creation time. */
       
  1638 				__( 'Draft created on %1$s at %2$s' ),
       
  1639 				gmdate( __( 'F j, Y' ), $now ),
       
  1640 				gmdate( __( 'g:i a' ), $now )
       
  1641 			);
  1584 
  1642 
  1585 			$pid = edit_post( $post_data );
  1643 			$pid = edit_post( $post_data );
  1586 
  1644 
  1587 			if ( $pid ) {
  1645 			if ( $pid ) {
  1588 				if ( is_wp_error( $pid ) ) {
  1646 				if ( is_wp_error( $pid ) ) {
  1643 			! current_user_can( 'edit_post_meta', $meta->post_id, $key )
  1701 			! current_user_can( 'edit_post_meta', $meta->post_id, $key )
  1644 		) {
  1702 		) {
  1645 			wp_die( -1 );
  1703 			wp_die( -1 );
  1646 		}
  1704 		}
  1647 
  1705 
  1648 		if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
  1706 		if ( $meta->meta_value !== $value || $meta->meta_key !== $key ) {
  1649 			$u = update_metadata_by_mid( 'post', $mid, $value, $key );
  1707 			$u = update_metadata_by_mid( 'post', $mid, $value, $key );
  1650 			if ( ! $u ) {
  1708 			if ( ! $u ) {
  1651 				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
  1709 				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
  1652 			}
  1710 			}
  1653 		}
  1711 		}
  1672 	}
  1730 	}
  1673 	$x->send();
  1731 	$x->send();
  1674 }
  1732 }
  1675 
  1733 
  1676 /**
  1734 /**
  1677  * Ajax handler for adding a user.
  1735  * Handles adding a user via AJAX.
  1678  *
  1736  *
  1679  * @since 3.1.0
  1737  * @since 3.1.0
  1680  *
  1738  *
  1681  * @param string $action Action to perform.
  1739  * @param string $action Action to perform.
  1682  */
  1740  */
  1727 	);
  1785 	);
  1728 	$x->send();
  1786 	$x->send();
  1729 }
  1787 }
  1730 
  1788 
  1731 /**
  1789 /**
  1732  * Ajax handler for closed post boxes.
  1790  * Handles closed post boxes via AJAX.
  1733  *
  1791  *
  1734  * @since 3.1.0
  1792  * @since 3.1.0
  1735  */
  1793  */
  1736 function wp_ajax_closed_postboxes() {
  1794 function wp_ajax_closed_postboxes() {
  1737 	check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
  1795 	check_ajax_referer( 'closedpostboxes', 'closedpostboxesnonce' );
  1741 	$hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1799 	$hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1742 	$hidden = array_filter( $hidden );
  1800 	$hidden = array_filter( $hidden );
  1743 
  1801 
  1744 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1802 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1745 
  1803 
  1746 	if ( sanitize_key( $page ) != $page ) {
  1804 	if ( sanitize_key( $page ) !== $page ) {
  1747 		wp_die( 0 );
  1805 		wp_die( 0 );
  1748 	}
  1806 	}
  1749 
  1807 
  1750 	$user = wp_get_current_user();
  1808 	$user = wp_get_current_user();
  1751 	if ( ! $user ) {
  1809 	if ( ! $user ) {
  1764 
  1822 
  1765 	wp_die( 1 );
  1823 	wp_die( 1 );
  1766 }
  1824 }
  1767 
  1825 
  1768 /**
  1826 /**
  1769  * Ajax handler for hidden columns.
  1827  * Handles hidden columns via AJAX.
  1770  *
  1828  *
  1771  * @since 3.1.0
  1829  * @since 3.1.0
  1772  */
  1830  */
  1773 function wp_ajax_hidden_columns() {
  1831 function wp_ajax_hidden_columns() {
  1774 	check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
  1832 	check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
  1775 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1833 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1776 
  1834 
  1777 	if ( sanitize_key( $page ) != $page ) {
  1835 	if ( sanitize_key( $page ) !== $page ) {
  1778 		wp_die( 0 );
  1836 		wp_die( 0 );
  1779 	}
  1837 	}
  1780 
  1838 
  1781 	$user = wp_get_current_user();
  1839 	$user = wp_get_current_user();
  1782 	if ( ! $user ) {
  1840 	if ( ! $user ) {
  1788 
  1846 
  1789 	wp_die( 1 );
  1847 	wp_die( 1 );
  1790 }
  1848 }
  1791 
  1849 
  1792 /**
  1850 /**
  1793  * Ajax handler for updating whether to display the welcome panel.
  1851  * Handles updating whether to display the welcome panel via AJAX.
  1794  *
  1852  *
  1795  * @since 3.1.0
  1853  * @since 3.1.0
  1796  */
  1854  */
  1797 function wp_ajax_update_welcome_panel() {
  1855 function wp_ajax_update_welcome_panel() {
  1798 	check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
  1856 	check_ajax_referer( 'welcome-panel-nonce', 'welcomepanelnonce' );
  1805 
  1863 
  1806 	wp_die( 1 );
  1864 	wp_die( 1 );
  1807 }
  1865 }
  1808 
  1866 
  1809 /**
  1867 /**
  1810  * Ajax handler for retrieving menu meta boxes.
  1868  * Handles for retrieving menu meta boxes via AJAX.
  1811  *
  1869  *
  1812  * @since 3.1.0
  1870  * @since 3.1.0
  1813  */
  1871  */
  1814 function wp_ajax_menu_get_metabox() {
  1872 function wp_ajax_menu_get_metabox() {
  1815 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1873 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1856 
  1914 
  1857 	wp_die();
  1915 	wp_die();
  1858 }
  1916 }
  1859 
  1917 
  1860 /**
  1918 /**
  1861  * Ajax handler for internal linking.
  1919  * Handles internal linking via AJAX.
  1862  *
  1920  *
  1863  * @since 3.1.0
  1921  * @since 3.1.0
  1864  */
  1922  */
  1865 function wp_ajax_wp_link_ajax() {
  1923 function wp_ajax_wp_link_ajax() {
  1866 	check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
  1924 	check_ajax_referer( 'internal-linking', '_ajax_linking_nonce' );
  1892 
  1950 
  1893 	wp_die();
  1951 	wp_die();
  1894 }
  1952 }
  1895 
  1953 
  1896 /**
  1954 /**
  1897  * Ajax handler for menu locations save.
  1955  * Handles saving menu locations via AJAX.
  1898  *
  1956  *
  1899  * @since 3.1.0
  1957  * @since 3.1.0
  1900  */
  1958  */
  1901 function wp_ajax_menu_locations_save() {
  1959 function wp_ajax_menu_locations_save() {
  1902 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1960 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1912 	set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
  1970 	set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
  1913 	wp_die( 1 );
  1971 	wp_die( 1 );
  1914 }
  1972 }
  1915 
  1973 
  1916 /**
  1974 /**
  1917  * Ajax handler for saving the meta box order.
  1975  * Handles saving the meta box order via AJAX.
  1918  *
  1976  *
  1919  * @since 3.1.0
  1977  * @since 3.1.0
  1920  */
  1978  */
  1921 function wp_ajax_meta_box_order() {
  1979 function wp_ajax_meta_box_order() {
  1922 	check_ajax_referer( 'meta-box-order' );
  1980 	check_ajax_referer( 'meta-box-order' );
  1927 		$page_columns = (int) $page_columns;
  1985 		$page_columns = (int) $page_columns;
  1928 	}
  1986 	}
  1929 
  1987 
  1930 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1988 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1931 
  1989 
  1932 	if ( sanitize_key( $page ) != $page ) {
  1990 	if ( sanitize_key( $page ) !== $page ) {
  1933 		wp_die( 0 );
  1991 		wp_die( 0 );
  1934 	}
  1992 	}
  1935 
  1993 
  1936 	$user = wp_get_current_user();
  1994 	$user = wp_get_current_user();
  1937 	if ( ! $user ) {
  1995 	if ( ! $user ) {
  1948 
  2006 
  1949 	wp_send_json_success();
  2007 	wp_send_json_success();
  1950 }
  2008 }
  1951 
  2009 
  1952 /**
  2010 /**
  1953  * Ajax handler for menu quick searching.
  2011  * Handles menu quick searching via AJAX.
  1954  *
  2012  *
  1955  * @since 3.1.0
  2013  * @since 3.1.0
  1956  */
  2014  */
  1957 function wp_ajax_menu_quick_search() {
  2015 function wp_ajax_menu_quick_search() {
  1958 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  2016 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1965 
  2023 
  1966 	wp_die();
  2024 	wp_die();
  1967 }
  2025 }
  1968 
  2026 
  1969 /**
  2027 /**
  1970  * Ajax handler to retrieve a permalink.
  2028  * Handles retrieving a permalink via AJAX.
  1971  *
  2029  *
  1972  * @since 3.1.0
  2030  * @since 3.1.0
  1973  */
  2031  */
  1974 function wp_ajax_get_permalink() {
  2032 function wp_ajax_get_permalink() {
  1975 	check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
  2033 	check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
  1976 	$post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
  2034 	$post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
  1977 	wp_die( get_preview_post_link( $post_id ) );
  2035 	wp_die( get_preview_post_link( $post_id ) );
  1978 }
  2036 }
  1979 
  2037 
  1980 /**
  2038 /**
  1981  * Ajax handler to retrieve a sample permalink.
  2039  * Handles retrieving a sample permalink via AJAX.
  1982  *
  2040  *
  1983  * @since 3.1.0
  2041  * @since 3.1.0
  1984  */
  2042  */
  1985 function wp_ajax_sample_permalink() {
  2043 function wp_ajax_sample_permalink() {
  1986 	check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
  2044 	check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
  1989 	$slug    = isset( $_POST['new_slug'] ) ? $_POST['new_slug'] : null;
  2047 	$slug    = isset( $_POST['new_slug'] ) ? $_POST['new_slug'] : null;
  1990 	wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
  2048 	wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
  1991 }
  2049 }
  1992 
  2050 
  1993 /**
  2051 /**
  1994  * Ajax handler for Quick Edit saving a post from a list table.
  2052  * Handles Quick Edit saving a post from a list table via AJAX.
  1995  *
  2053  *
  1996  * @since 3.1.0
  2054  * @since 3.1.0
  1997  *
  2055  *
  1998  * @global string $mode List table view mode.
  2056  * @global string $mode List table view mode.
  1999  */
  2057  */
  2004 
  2062 
  2005 	if ( ! isset( $_POST['post_ID'] ) || ! (int) $_POST['post_ID'] ) {
  2063 	if ( ! isset( $_POST['post_ID'] ) || ! (int) $_POST['post_ID'] ) {
  2006 		wp_die();
  2064 		wp_die();
  2007 	}
  2065 	}
  2008 
  2066 
  2009 	$post_ID = (int) $_POST['post_ID'];
  2067 	$post_id = (int) $_POST['post_ID'];
  2010 
  2068 
  2011 	if ( 'page' === $_POST['post_type'] ) {
  2069 	if ( 'page' === $_POST['post_type'] ) {
  2012 		if ( ! current_user_can( 'edit_page', $post_ID ) ) {
  2070 		if ( ! current_user_can( 'edit_page', $post_id ) ) {
  2013 			wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
  2071 			wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
  2014 		}
  2072 		}
  2015 	} else {
  2073 	} else {
  2016 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  2074 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2017 			wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  2075 			wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  2018 		}
  2076 		}
  2019 	}
  2077 	}
  2020 
  2078 
  2021 	$last = wp_check_post_lock( $post_ID );
  2079 	$last = wp_check_post_lock( $post_id );
  2022 	if ( $last ) {
  2080 	if ( $last ) {
  2023 		$last_user      = get_userdata( $last );
  2081 		$last_user      = get_userdata( $last );
  2024 		$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
  2082 		$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
  2025 
  2083 
  2026 		/* translators: %s: User's display name. */
  2084 		/* translators: %s: User's display name. */
  2035 		wp_die();
  2093 		wp_die();
  2036 	}
  2094 	}
  2037 
  2095 
  2038 	$data = &$_POST;
  2096 	$data = &$_POST;
  2039 
  2097 
  2040 	$post = get_post( $post_ID, ARRAY_A );
  2098 	$post = get_post( $post_id, ARRAY_A );
  2041 
  2099 
  2042 	// Since it's coming from the database.
  2100 	// Since it's coming from the database.
  2043 	$post = wp_slash( $post );
  2101 	$post = wp_slash( $post );
  2044 
  2102 
  2045 	$data['content'] = $post['post_content'];
  2103 	$data['content'] = $post['post_content'];
  2098 		$parent       = $request_post[0]->post_parent;
  2156 		$parent       = $request_post[0]->post_parent;
  2099 
  2157 
  2100 		while ( $parent > 0 ) {
  2158 		while ( $parent > 0 ) {
  2101 			$parent_post = get_post( $parent );
  2159 			$parent_post = get_post( $parent );
  2102 			$parent      = $parent_post->post_parent;
  2160 			$parent      = $parent_post->post_parent;
  2103 			$level++;
  2161 			++$level;
  2104 		}
  2162 		}
  2105 	}
  2163 	}
  2106 
  2164 
  2107 	$wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
  2165 	$wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );
  2108 
  2166 
  2109 	wp_die();
  2167 	wp_die();
  2110 }
  2168 }
  2111 
  2169 
  2112 /**
  2170 /**
  2113  * Ajax handler for quick edit saving for a term.
  2171  * Handles Quick Edit saving for a term via AJAX.
  2114  *
  2172  *
  2115  * @since 3.1.0
  2173  * @since 3.1.0
  2116  */
  2174  */
  2117 function wp_ajax_inline_save_tax() {
  2175 function wp_ajax_inline_save_tax() {
  2118 	check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
  2176 	check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
  2119 
  2177 
  2120 	$taxonomy = sanitize_key( $_POST['taxonomy'] );
  2178 	$taxonomy        = sanitize_key( $_POST['taxonomy'] );
  2121 	$tax      = get_taxonomy( $taxonomy );
  2179 	$taxonomy_object = get_taxonomy( $taxonomy );
  2122 
  2180 
  2123 	if ( ! $tax ) {
  2181 	if ( ! $taxonomy_object ) {
  2124 		wp_die( 0 );
  2182 		wp_die( 0 );
  2125 	}
  2183 	}
  2126 
  2184 
  2127 	if ( ! isset( $_POST['tax_ID'] ) || ! (int) $_POST['tax_ID'] ) {
  2185 	if ( ! isset( $_POST['tax_ID'] ) || ! (int) $_POST['tax_ID'] ) {
  2128 		wp_die( -1 );
  2186 		wp_die( -1 );
  2160 	$parent = $tag->parent;
  2218 	$parent = $tag->parent;
  2161 
  2219 
  2162 	while ( $parent > 0 ) {
  2220 	while ( $parent > 0 ) {
  2163 		$parent_tag = get_term( $parent, $taxonomy );
  2221 		$parent_tag = get_term( $parent, $taxonomy );
  2164 		$parent     = $parent_tag->parent;
  2222 		$parent     = $parent_tag->parent;
  2165 		$level++;
  2223 		++$level;
  2166 	}
  2224 	}
  2167 
  2225 
  2168 	$wp_list_table->single_row( $tag, $level );
  2226 	$wp_list_table->single_row( $tag, $level );
  2169 	wp_die();
  2227 	wp_die();
  2170 }
  2228 }
  2171 
  2229 
  2172 /**
  2230 /**
  2173  * Ajax handler for querying posts for the Find Posts modal.
  2231  * Handles querying posts for the Find Posts modal via AJAX.
  2174  *
  2232  *
  2175  * @see window.findPosts
  2233  * @see window.findPosts
  2176  *
  2234  *
  2177  * @since 3.1.0
  2235  * @since 3.1.0
  2178  */
  2236  */
  2180 	check_ajax_referer( 'find-posts' );
  2238 	check_ajax_referer( 'find-posts' );
  2181 
  2239 
  2182 	$post_types = get_post_types( array( 'public' => true ), 'objects' );
  2240 	$post_types = get_post_types( array( 'public' => true ), 'objects' );
  2183 	unset( $post_types['attachment'] );
  2241 	unset( $post_types['attachment'] );
  2184 
  2242 
  2185 	$s    = wp_unslash( $_POST['ps'] );
       
  2186 	$args = array(
  2243 	$args = array(
  2187 		'post_type'      => array_keys( $post_types ),
  2244 		'post_type'      => array_keys( $post_types ),
  2188 		'post_status'    => 'any',
  2245 		'post_status'    => 'any',
  2189 		'posts_per_page' => 50,
  2246 		'posts_per_page' => 50,
  2190 	);
  2247 	);
  2191 
  2248 
  2192 	if ( '' !== $s ) {
  2249 	$search = wp_unslash( $_POST['ps'] );
  2193 		$args['s'] = $s;
  2250 
       
  2251 	if ( '' !== $search ) {
       
  2252 		$args['s'] = $search;
  2194 	}
  2253 	}
  2195 
  2254 
  2196 	$posts = get_posts( $args );
  2255 	$posts = get_posts( $args );
  2197 
  2256 
  2198 	if ( ! $posts ) {
  2257 	if ( ! $posts ) {
  2236 
  2295 
  2237 	wp_send_json_success( $html );
  2296 	wp_send_json_success( $html );
  2238 }
  2297 }
  2239 
  2298 
  2240 /**
  2299 /**
  2241  * Ajax handler for saving the widgets order.
  2300  * Handles saving the widgets order via AJAX.
  2242  *
  2301  *
  2243  * @since 3.1.0
  2302  * @since 3.1.0
  2244  */
  2303  */
  2245 function wp_ajax_widgets_order() {
  2304 function wp_ajax_widgets_order() {
  2246 	check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
  2305 	check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
  2260 
  2319 
  2261 			if ( ! empty( $val ) ) {
  2320 			if ( ! empty( $val ) ) {
  2262 				$val = explode( ',', $val );
  2321 				$val = explode( ',', $val );
  2263 
  2322 
  2264 				foreach ( $val as $k => $v ) {
  2323 				foreach ( $val as $k => $v ) {
  2265 					if ( strpos( $v, 'widget-' ) === false ) {
  2324 					if ( ! str_contains( $v, 'widget-' ) ) {
  2266 						continue;
  2325 						continue;
  2267 					}
  2326 					}
  2268 
  2327 
  2269 					$sb[ $k ] = substr( $v, strpos( $v, '_' ) + 1 );
  2328 					$sb[ $k ] = substr( $v, strpos( $v, '_' ) + 1 );
  2270 				}
  2329 				}
  2278 
  2337 
  2279 	wp_die( -1 );
  2338 	wp_die( -1 );
  2280 }
  2339 }
  2281 
  2340 
  2282 /**
  2341 /**
  2283  * Ajax handler for saving a widget.
  2342  * Handles saving a widget via AJAX.
  2284  *
  2343  *
  2285  * @since 3.1.0
  2344  * @since 3.1.0
  2286  *
  2345  *
  2287  * @global array $wp_registered_widgets
  2346  * @global array $wp_registered_widgets
  2288  * @global array $wp_registered_widget_controls
  2347  * @global array $wp_registered_widget_controls
  2355 	}
  2414 	}
  2356 	$_POST['widget-id'] = $sidebar;
  2415 	$_POST['widget-id'] = $sidebar;
  2357 
  2416 
  2358 	foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
  2417 	foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
  2359 
  2418 
  2360 		if ( $name == $id_base ) {
  2419 		if ( $name === $id_base ) {
  2361 			if ( ! is_callable( $control['callback'] ) ) {
  2420 			if ( ! is_callable( $control['callback'] ) ) {
  2362 				continue;
  2421 				continue;
  2363 			}
  2422 			}
  2364 
  2423 
  2365 			ob_start();
  2424 			ob_start();
  2387 
  2446 
  2388 	wp_die();
  2447 	wp_die();
  2389 }
  2448 }
  2390 
  2449 
  2391 /**
  2450 /**
  2392  * Ajax handler for updating a widget.
  2451  * Handles updating a widget via AJAX.
  2393  *
  2452  *
  2394  * @since 3.9.0
  2453  * @since 3.9.0
  2395  *
  2454  *
  2396  * @global WP_Customize_Manager $wp_customize
  2455  * @global WP_Customize_Manager $wp_customize
  2397  */
  2456  */
  2399 	global $wp_customize;
  2458 	global $wp_customize;
  2400 	$wp_customize->widgets->wp_ajax_update_widget();
  2459 	$wp_customize->widgets->wp_ajax_update_widget();
  2401 }
  2460 }
  2402 
  2461 
  2403 /**
  2462 /**
  2404  * Ajax handler for removing inactive widgets.
  2463  * Handles removing inactive widgets via AJAX.
  2405  *
  2464  *
  2406  * @since 4.4.0
  2465  * @since 4.4.0
  2407  */
  2466  */
  2408 function wp_ajax_delete_inactive_widgets() {
  2467 function wp_ajax_delete_inactive_widgets() {
  2409 	check_ajax_referer( 'remove-inactive-widgets', 'removeinactivewidgets' );
  2468 	check_ajax_referer( 'remove-inactive-widgets', 'removeinactivewidgets' );
  2436 
  2495 
  2437 	wp_die();
  2496 	wp_die();
  2438 }
  2497 }
  2439 
  2498 
  2440 /**
  2499 /**
  2441  * Ajax handler for creating missing image sub-sizes for just uploaded images.
  2500  * Handles creating missing image sub-sizes for just uploaded images via AJAX.
  2442  *
  2501  *
  2443  * @since 5.3.0
  2502  * @since 5.3.0
  2444  */
  2503  */
  2445 function wp_ajax_media_create_image_subsizes() {
  2504 function wp_ajax_media_create_image_subsizes() {
  2446 	check_ajax_referer( 'media-form' );
  2505 	check_ajax_referer( 'media-form' );
  2466 				wp_send_json_success();
  2525 				wp_send_json_success();
  2467 			}
  2526 			}
  2468 		}
  2527 		}
  2469 	}
  2528 	}
  2470 
  2529 
  2471 	// Set a custom header with the attachment_id.
  2530 	/*
  2472 	// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
  2531 	 * Set a custom header with the attachment_id.
       
  2532 	 * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
       
  2533 	 */
  2473 	if ( ! headers_sent() ) {
  2534 	if ( ! headers_sent() ) {
  2474 		header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
  2535 		header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
  2475 	}
  2536 	}
  2476 
  2537 
  2477 	// This can still be pretty slow and cause timeout or out of memory errors.
  2538 	/*
  2478 	// The js that handles the response would need to also handle HTTP 500 errors.
  2539 	 * This can still be pretty slow and cause timeout or out of memory errors.
       
  2540 	 * The js that handles the response would need to also handle HTTP 500 errors.
       
  2541 	 */
  2479 	wp_update_image_subsizes( $attachment_id );
  2542 	wp_update_image_subsizes( $attachment_id );
  2480 
  2543 
  2481 	if ( ! empty( $_POST['_legacy_support'] ) ) {
  2544 	if ( ! empty( $_POST['_legacy_support'] ) ) {
  2482 		// The old (inline) uploader. Only needs the attachment_id.
  2545 		// The old (inline) uploader. Only needs the attachment_id.
  2483 		$response = array( 'id' => $attachment_id );
  2546 		$response = array( 'id' => $attachment_id );
  2493 	// At this point the image has been uploaded successfully.
  2556 	// At this point the image has been uploaded successfully.
  2494 	wp_send_json_success( $response );
  2557 	wp_send_json_success( $response );
  2495 }
  2558 }
  2496 
  2559 
  2497 /**
  2560 /**
  2498  * Ajax handler for uploading attachments
  2561  * Handles uploading attachments via AJAX.
  2499  *
  2562  *
  2500  * @since 3.3.0
  2563  * @since 3.3.0
  2501  */
  2564  */
  2502 function wp_ajax_upload_attachment() {
  2565 function wp_ajax_upload_attachment() {
  2503 	check_ajax_referer( 'media-form' );
  2566 	check_ajax_referer( 'media-form' );
  2504 	/*
  2567 	/*
  2505 	 * This function does not use wp_send_json_success() / wp_send_json_error()
  2568 	 * This function does not use wp_send_json_success() / wp_send_json_error()
  2506 	 * as the html4 Plupload handler requires a text/html content-type for older IE.
  2569 	 * as the html4 Plupload handler requires a text/html Content-Type for older IE.
  2507 	 * See https://core.trac.wordpress.org/ticket/31037
  2570 	 * See https://core.trac.wordpress.org/ticket/31037
  2508 	 */
  2571 	 */
  2509 
  2572 
  2510 	if ( ! current_user_can( 'upload_files' ) ) {
  2573 	if ( ! current_user_can( 'upload_files' ) ) {
  2511 		echo wp_json_encode(
  2574 		echo wp_json_encode(
  2606 
  2669 
  2607 	wp_die();
  2670 	wp_die();
  2608 }
  2671 }
  2609 
  2672 
  2610 /**
  2673 /**
  2611  * Ajax handler for image editing.
  2674  * Handles image editing via AJAX.
  2612  *
  2675  *
  2613  * @since 3.1.0
  2676  * @since 3.1.0
  2614  */
  2677  */
  2615 function wp_ajax_image_editor() {
  2678 function wp_ajax_image_editor() {
  2616 	$attachment_id = (int) $_POST['postid'];
  2679 	$attachment_id = (int) $_POST['postid'];
  2618 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  2681 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  2619 		wp_die( -1 );
  2682 		wp_die( -1 );
  2620 	}
  2683 	}
  2621 
  2684 
  2622 	check_ajax_referer( "image_editor-$attachment_id" );
  2685 	check_ajax_referer( "image_editor-$attachment_id" );
  2623 	include_once ABSPATH . 'wp-admin/includes/image-edit.php';
  2686 	require_once ABSPATH . 'wp-admin/includes/image-edit.php';
  2624 
  2687 
  2625 	$msg = false;
  2688 	$msg = false;
  2626 
  2689 
  2627 	switch ( $_POST['do'] ) {
  2690 	switch ( $_POST['do'] ) {
  2628 		case 'save':
  2691 		case 'save':
  2661 		)
  2724 		)
  2662 	);
  2725 	);
  2663 }
  2726 }
  2664 
  2727 
  2665 /**
  2728 /**
  2666  * Ajax handler for setting the featured image.
  2729  * Handles setting the featured image via AJAX.
  2667  *
  2730  *
  2668  * @since 3.1.0
  2731  * @since 3.1.0
  2669  */
  2732  */
  2670 function wp_ajax_set_post_thumbnail() {
  2733 function wp_ajax_set_post_thumbnail() {
  2671 	$json = ! empty( $_REQUEST['json'] ); // New-style request.
  2734 	$json = ! empty( $_REQUEST['json'] ); // New-style request.
  2672 
  2735 
  2673 	$post_ID = (int) $_POST['post_id'];
  2736 	$post_id = (int) $_POST['post_id'];
  2674 	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  2737 	if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2675 		wp_die( -1 );
  2738 		wp_die( -1 );
  2676 	}
  2739 	}
  2677 
  2740 
  2678 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2741 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2679 
  2742 
  2680 	if ( $json ) {
  2743 	if ( $json ) {
  2681 		check_ajax_referer( "update-post_$post_ID" );
  2744 		check_ajax_referer( "update-post_$post_id" );
  2682 	} else {
  2745 	} else {
  2683 		check_ajax_referer( "set_post_thumbnail-$post_ID" );
  2746 		check_ajax_referer( "set_post_thumbnail-$post_id" );
  2684 	}
  2747 	}
  2685 
  2748 
  2686 	if ( '-1' == $thumbnail_id ) {
  2749 	if ( -1 === $thumbnail_id ) {
  2687 		if ( delete_post_thumbnail( $post_ID ) ) {
  2750 		if ( delete_post_thumbnail( $post_id ) ) {
  2688 			$return = _wp_post_thumbnail_html( null, $post_ID );
  2751 			$return = _wp_post_thumbnail_html( null, $post_id );
  2689 			$json ? wp_send_json_success( $return ) : wp_die( $return );
  2752 			$json ? wp_send_json_success( $return ) : wp_die( $return );
  2690 		} else {
  2753 		} else {
  2691 			wp_die( 0 );
  2754 			wp_die( 0 );
  2692 		}
  2755 		}
  2693 	}
  2756 	}
  2694 
  2757 
  2695 	if ( set_post_thumbnail( $post_ID, $thumbnail_id ) ) {
  2758 	if ( set_post_thumbnail( $post_id, $thumbnail_id ) ) {
  2696 		$return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
  2759 		$return = _wp_post_thumbnail_html( $thumbnail_id, $post_id );
  2697 		$json ? wp_send_json_success( $return ) : wp_die( $return );
  2760 		$json ? wp_send_json_success( $return ) : wp_die( $return );
  2698 	}
  2761 	}
  2699 
  2762 
  2700 	wp_die( 0 );
  2763 	wp_die( 0 );
  2701 }
  2764 }
  2702 
  2765 
  2703 /**
  2766 /**
  2704  * Ajax handler for retrieving HTML for the featured image.
  2767  * Handles retrieving HTML for the featured image via AJAX.
  2705  *
  2768  *
  2706  * @since 4.6.0
  2769  * @since 4.6.0
  2707  */
  2770  */
  2708 function wp_ajax_get_post_thumbnail_html() {
  2771 function wp_ajax_get_post_thumbnail_html() {
  2709 	$post_ID = (int) $_POST['post_id'];
  2772 	$post_id = (int) $_POST['post_id'];
  2710 
  2773 
  2711 	check_ajax_referer( "update-post_$post_ID" );
  2774 	check_ajax_referer( "update-post_$post_id" );
  2712 
  2775 
  2713 	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  2776 	if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2714 		wp_die( -1 );
  2777 		wp_die( -1 );
  2715 	}
  2778 	}
  2716 
  2779 
  2717 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2780 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2718 
  2781 
  2719 	// For backward compatibility, -1 refers to no featured image.
  2782 	// For backward compatibility, -1 refers to no featured image.
  2720 	if ( -1 === $thumbnail_id ) {
  2783 	if ( -1 === $thumbnail_id ) {
  2721 		$thumbnail_id = null;
  2784 		$thumbnail_id = null;
  2722 	}
  2785 	}
  2723 
  2786 
  2724 	$return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
  2787 	$return = _wp_post_thumbnail_html( $thumbnail_id, $post_id );
  2725 	wp_send_json_success( $return );
  2788 	wp_send_json_success( $return );
  2726 }
  2789 }
  2727 
  2790 
  2728 /**
  2791 /**
  2729  * Ajax handler for setting the featured image for an attachment.
  2792  * Handles setting the featured image for an attachment via AJAX.
  2730  *
  2793  *
  2731  * @since 4.0.0
  2794  * @since 4.0.0
  2732  *
  2795  *
  2733  * @see set_post_thumbnail()
  2796  * @see set_post_thumbnail()
  2734  */
  2797  */
  2737 		wp_send_json_error();
  2800 		wp_send_json_error();
  2738 	}
  2801 	}
  2739 
  2802 
  2740 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2803 	$thumbnail_id = (int) $_POST['thumbnail_id'];
  2741 	if ( empty( $thumbnail_id ) ) {
  2804 	if ( empty( $thumbnail_id ) ) {
       
  2805 		wp_send_json_error();
       
  2806 	}
       
  2807 
       
  2808 	if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
  2742 		wp_send_json_error();
  2809 		wp_send_json_error();
  2743 	}
  2810 	}
  2744 
  2811 
  2745 	$post_ids = array();
  2812 	$post_ids = array();
  2746 	// For each URL, try to find its corresponding post ID.
  2813 	// For each URL, try to find its corresponding post ID.
  2761 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2828 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2762 			continue;
  2829 			continue;
  2763 		}
  2830 		}
  2764 
  2831 
  2765 		if ( set_post_thumbnail( $post_id, $thumbnail_id ) ) {
  2832 		if ( set_post_thumbnail( $post_id, $thumbnail_id ) ) {
  2766 			$success++;
  2833 			++$success;
  2767 		}
  2834 		}
  2768 	}
  2835 	}
  2769 
  2836 
  2770 	if ( 0 === $success ) {
  2837 	if ( 0 === $success ) {
  2771 		wp_send_json_error();
  2838 		wp_send_json_error();
  2775 
  2842 
  2776 	wp_send_json_error();
  2843 	wp_send_json_error();
  2777 }
  2844 }
  2778 
  2845 
  2779 /**
  2846 /**
  2780  * Ajax handler for date formatting.
  2847  * Handles formatting a date via AJAX.
  2781  *
  2848  *
  2782  * @since 3.1.0
  2849  * @since 3.1.0
  2783  */
  2850  */
  2784 function wp_ajax_date_format() {
  2851 function wp_ajax_date_format() {
  2785 	wp_die( date_i18n( sanitize_option( 'date_format', wp_unslash( $_POST['date'] ) ) ) );
  2852 	wp_die( date_i18n( sanitize_option( 'date_format', wp_unslash( $_POST['date'] ) ) ) );
  2786 }
  2853 }
  2787 
  2854 
  2788 /**
  2855 /**
  2789  * Ajax handler for time formatting.
  2856  * Handles formatting a time via AJAX.
  2790  *
  2857  *
  2791  * @since 3.1.0
  2858  * @since 3.1.0
  2792  */
  2859  */
  2793 function wp_ajax_time_format() {
  2860 function wp_ajax_time_format() {
  2794 	wp_die( date_i18n( sanitize_option( 'time_format', wp_unslash( $_POST['date'] ) ) ) );
  2861 	wp_die( date_i18n( sanitize_option( 'time_format', wp_unslash( $_POST['date'] ) ) ) );
  2795 }
  2862 }
  2796 
  2863 
  2797 /**
  2864 /**
  2798  * Ajax handler for saving posts from the fullscreen editor.
  2865  * Handles saving posts from the fullscreen editor via AJAX.
  2799  *
  2866  *
  2800  * @since 3.1.0
  2867  * @since 3.1.0
  2801  * @deprecated 4.3.0
  2868  * @deprecated 4.3.0
  2802  */
  2869  */
  2803 function wp_ajax_wp_fullscreen_save_post() {
  2870 function wp_ajax_wp_fullscreen_save_post() {
  2837 
  2904 
  2838 	wp_send_json_success( array( 'last_edited' => $last_edited ) );
  2905 	wp_send_json_success( array( 'last_edited' => $last_edited ) );
  2839 }
  2906 }
  2840 
  2907 
  2841 /**
  2908 /**
  2842  * Ajax handler for removing a post lock.
  2909  * Handles removing a post lock via AJAX.
  2843  *
  2910  *
  2844  * @since 3.1.0
  2911  * @since 3.1.0
  2845  */
  2912  */
  2846 function wp_ajax_wp_remove_post_lock() {
  2913 function wp_ajax_wp_remove_post_lock() {
  2847 	if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) ) {
  2914 	if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) ) {
  2861 		wp_die( -1 );
  2928 		wp_die( -1 );
  2862 	}
  2929 	}
  2863 
  2930 
  2864 	$active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
  2931 	$active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
  2865 
  2932 
  2866 	if ( get_current_user_id() != $active_lock[1] ) {
  2933 	if ( get_current_user_id() !== $active_lock[1] ) {
  2867 		wp_die( 0 );
  2934 		wp_die( 0 );
  2868 	}
  2935 	}
  2869 
  2936 
  2870 	/**
  2937 	/**
  2871 	 * Filters the post lock window duration.
  2938 	 * Filters the post lock window duration.
  2879 	update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
  2946 	update_post_meta( $post_id, '_edit_lock', $new_lock, implode( ':', $active_lock ) );
  2880 	wp_die( 1 );
  2947 	wp_die( 1 );
  2881 }
  2948 }
  2882 
  2949 
  2883 /**
  2950 /**
  2884  * Ajax handler for dismissing a WordPress pointer.
  2951  * Handles dismissing a WordPress pointer via AJAX.
  2885  *
  2952  *
  2886  * @since 3.1.0
  2953  * @since 3.1.0
  2887  */
  2954  */
  2888 function wp_ajax_dismiss_wp_pointer() {
  2955 function wp_ajax_dismiss_wp_pointer() {
  2889 	$pointer = $_POST['pointer'];
  2956 	$pointer = $_POST['pointer'];
  2890 
  2957 
  2891 	if ( sanitize_key( $pointer ) != $pointer ) {
  2958 	if ( sanitize_key( $pointer ) !== $pointer ) {
  2892 		wp_die( 0 );
  2959 		wp_die( 0 );
  2893 	}
  2960 	}
  2894 
  2961 
  2895 	//  check_ajax_referer( 'dismiss-pointer_' . $pointer );
  2962 	//  check_ajax_referer( 'dismiss-pointer_' . $pointer );
  2896 
  2963 
  2906 	update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
  2973 	update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $dismissed );
  2907 	wp_die( 1 );
  2974 	wp_die( 1 );
  2908 }
  2975 }
  2909 
  2976 
  2910 /**
  2977 /**
  2911  * Ajax handler for getting an attachment.
  2978  * Handles getting an attachment via AJAX.
  2912  *
  2979  *
  2913  * @since 3.5.0
  2980  * @since 3.5.0
  2914  */
  2981  */
  2915 function wp_ajax_get_attachment() {
  2982 function wp_ajax_get_attachment() {
  2916 	if ( ! isset( $_REQUEST['id'] ) ) {
  2983 	if ( ! isset( $_REQUEST['id'] ) ) {
  2942 
  3009 
  2943 	wp_send_json_success( $attachment );
  3010 	wp_send_json_success( $attachment );
  2944 }
  3011 }
  2945 
  3012 
  2946 /**
  3013 /**
  2947  * Ajax handler for querying attachments.
  3014  * Handles querying attachments via AJAX.
  2948  *
  3015  *
  2949  * @since 3.5.0
  3016  * @since 3.5.0
  2950  */
  3017  */
  2951 function wp_ajax_query_attachments() {
  3018 function wp_ajax_query_attachments() {
  2952 	if ( ! current_user_can( 'upload_files' ) ) {
  3019 	if ( ! current_user_can( 'upload_files' ) ) {
  2992 		$query['post_status'] .= ',private';
  3059 		$query['post_status'] .= ',private';
  2993 	}
  3060 	}
  2994 
  3061 
  2995 	// Filter query clauses to include filenames.
  3062 	// Filter query clauses to include filenames.
  2996 	if ( isset( $query['s'] ) ) {
  3063 	if ( isset( $query['s'] ) ) {
  2997 		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
  3064 		add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
  2998 	}
  3065 	}
  2999 
  3066 
  3000 	/**
  3067 	/**
  3001 	 * Filters the arguments passed to WP_Query during an Ajax
  3068 	 * Filters the arguments passed to WP_Query during an Ajax
  3002 	 * call for querying attachments.
  3069 	 * call for querying attachments.
  3007 	 *
  3074 	 *
  3008 	 * @param array $query An array of query variables.
  3075 	 * @param array $query An array of query variables.
  3009 	 */
  3076 	 */
  3010 	$query             = apply_filters( 'ajax_query_attachments_args', $query );
  3077 	$query             = apply_filters( 'ajax_query_attachments_args', $query );
  3011 	$attachments_query = new WP_Query( $query );
  3078 	$attachments_query = new WP_Query( $query );
       
  3079 	update_post_parent_caches( $attachments_query->posts );
  3012 
  3080 
  3013 	$posts       = array_map( 'wp_prepare_attachment_for_js', $attachments_query->posts );
  3081 	$posts       = array_map( 'wp_prepare_attachment_for_js', $attachments_query->posts );
  3014 	$posts       = array_filter( $posts );
  3082 	$posts       = array_filter( $posts );
  3015 	$total_posts = $attachments_query->found_posts;
  3083 	$total_posts = $attachments_query->found_posts;
  3016 
  3084 
  3023 		$total_posts = $count_query->found_posts;
  3091 		$total_posts = $count_query->found_posts;
  3024 	}
  3092 	}
  3025 
  3093 
  3026 	$posts_per_page = (int) $attachments_query->get( 'posts_per_page' );
  3094 	$posts_per_page = (int) $attachments_query->get( 'posts_per_page' );
  3027 
  3095 
  3028 	$max_pages = $posts_per_page ? ceil( $total_posts / $posts_per_page ) : 0;
  3096 	$max_pages = $posts_per_page ? (int) ceil( $total_posts / $posts_per_page ) : 0;
  3029 
  3097 
  3030 	header( 'X-WP-Total: ' . (int) $total_posts );
  3098 	header( 'X-WP-Total: ' . (int) $total_posts );
  3031 	header( 'X-WP-TotalPages: ' . (int) $max_pages );
  3099 	header( 'X-WP-TotalPages: ' . $max_pages );
  3032 
  3100 
  3033 	wp_send_json_success( $posts );
  3101 	wp_send_json_success( $posts );
  3034 }
  3102 }
  3035 
  3103 
  3036 /**
  3104 /**
  3037  * Ajax handler for updating attachment attributes.
  3105  * Handles updating attachment attributes via AJAX.
  3038  *
  3106  *
  3039  * @since 3.5.0
  3107  * @since 3.5.0
  3040  */
  3108  */
  3041 function wp_ajax_save_attachment() {
  3109 function wp_ajax_save_attachment() {
  3042 	if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) ) {
  3110 	if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) ) {
  3118 
  3186 
  3119 	wp_send_json_success();
  3187 	wp_send_json_success();
  3120 }
  3188 }
  3121 
  3189 
  3122 /**
  3190 /**
  3123  * Ajax handler for saving backward compatible attachment attributes.
  3191  * Handles saving backward compatible attachment attributes via AJAX.
  3124  *
  3192  *
  3125  * @since 3.5.0
  3193  * @since 3.5.0
  3126  */
  3194  */
  3127 function wp_ajax_save_attachment_compat() {
  3195 function wp_ajax_save_attachment_compat() {
  3128 	if ( ! isset( $_REQUEST['id'] ) ) {
  3196 	if ( ! isset( $_REQUEST['id'] ) ) {
  3176 
  3244 
  3177 	wp_send_json_success( $attachment );
  3245 	wp_send_json_success( $attachment );
  3178 }
  3246 }
  3179 
  3247 
  3180 /**
  3248 /**
  3181  * Ajax handler for saving the attachment order.
  3249  * Handles saving the attachment order via AJAX.
  3182  *
  3250  *
  3183  * @since 3.5.0
  3251  * @since 3.5.0
  3184  */
  3252  */
  3185 function wp_ajax_save_attachment_order() {
  3253 function wp_ajax_save_attachment_order() {
  3186 	if ( ! isset( $_REQUEST['post_id'] ) ) {
  3254 	if ( ! isset( $_REQUEST['post_id'] ) ) {
  3229 
  3297 
  3230 	wp_send_json_success();
  3298 	wp_send_json_success();
  3231 }
  3299 }
  3232 
  3300 
  3233 /**
  3301 /**
  3234  * Ajax handler for sending an attachment to the editor.
  3302  * Handles sending an attachment to the editor via AJAX.
  3235  *
  3303  *
  3236  * Generates the HTML to send an attachment to the editor.
  3304  * Generates the HTML to send an attachment to the editor.
  3237  * Backward compatible with the {@see 'media_send_to_editor'} filter
  3305  * Backward compatible with the {@see 'media_send_to_editor'} filter
  3238  * and the chain of filters that follow.
  3306  * and the chain of filters that follow.
  3239  *
  3307  *
  3257 
  3325 
  3258 	if ( current_user_can( 'edit_post', $id ) ) {
  3326 	if ( current_user_can( 'edit_post', $id ) ) {
  3259 		// If this attachment is unattached, attach it. Primarily a back compat thing.
  3327 		// If this attachment is unattached, attach it. Primarily a back compat thing.
  3260 		$insert_into_post_id = (int) $_POST['post_id'];
  3328 		$insert_into_post_id = (int) $_POST['post_id'];
  3261 
  3329 
  3262 		if ( 0 == $post->post_parent && $insert_into_post_id ) {
  3330 		if ( 0 === $post->post_parent && $insert_into_post_id ) {
  3263 			wp_update_post(
  3331 			wp_update_post(
  3264 				array(
  3332 				array(
  3265 					'ID'          => $id,
  3333 					'ID'          => $id,
  3266 					'post_parent' => $insert_into_post_id,
  3334 					'post_parent' => $insert_into_post_id,
  3267 				)
  3335 				)
  3268 			);
  3336 			);
  3269 		}
  3337 		}
  3270 	}
  3338 	}
  3271 
  3339 
  3272 	$url = empty( $attachment['url'] ) ? '' : $attachment['url'];
  3340 	$url = empty( $attachment['url'] ) ? '' : $attachment['url'];
  3273 	$rel = ( strpos( $url, 'attachment_id' ) || get_attachment_link( $id ) == $url );
  3341 	$rel = ( str_contains( $url, 'attachment_id' ) || get_attachment_link( $id ) === $url );
  3274 
  3342 
  3275 	remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' );
  3343 	remove_filter( 'media_send_to_editor', 'image_media_send_to_editor' );
  3276 
  3344 
  3277 	if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
  3345 	if ( str_starts_with( $post->post_mime_type, 'image' ) ) {
  3278 		$align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
  3346 		$align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
  3279 		$size  = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
  3347 		$size  = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
  3280 		$alt   = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
  3348 		$alt   = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
  3281 
  3349 
  3282 		// No whitespace-only captions.
  3350 		// No whitespace-only captions.
  3303 
  3371 
  3304 	wp_send_json_success( $html );
  3372 	wp_send_json_success( $html );
  3305 }
  3373 }
  3306 
  3374 
  3307 /**
  3375 /**
  3308  * Ajax handler for sending a link to the editor.
  3376  * Handles sending a link to the editor via AJAX.
  3309  *
  3377  *
  3310  * Generates the HTML to send a non-image embed link to the editor.
  3378  * Generates the HTML to send a non-image embed link to the editor.
  3311  *
  3379  *
  3312  * Backward compatible with the following filters:
  3380  * Backward compatible with the following filters:
  3313  * - file_send_to_editor_url
  3381  * - file_send_to_editor_url
  3315  * - video_send_to_editor_url
  3383  * - video_send_to_editor_url
  3316  *
  3384  *
  3317  * @since 3.5.0
  3385  * @since 3.5.0
  3318  *
  3386  *
  3319  * @global WP_Post  $post     Global post object.
  3387  * @global WP_Post  $post     Global post object.
  3320  * @global WP_Embed $wp_embed
  3388  * @global WP_Embed $wp_embed WordPress Embed object.
  3321  */
  3389  */
  3322 function wp_ajax_send_link_to_editor() {
  3390 function wp_ajax_send_link_to_editor() {
  3323 	global $post, $wp_embed;
  3391 	global $post, $wp_embed;
  3324 
  3392 
  3325 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
  3393 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
  3331 
  3399 
  3332 	if ( ! strpos( $src, '://' ) ) {
  3400 	if ( ! strpos( $src, '://' ) ) {
  3333 		$src = 'http://' . $src;
  3401 		$src = 'http://' . $src;
  3334 	}
  3402 	}
  3335 
  3403 
  3336 	$src = esc_url_raw( $src );
  3404 	$src = sanitize_url( $src );
  3337 	if ( ! $src ) {
  3405 	if ( ! $src ) {
  3338 		wp_send_json_error();
  3406 		wp_send_json_error();
  3339 	}
  3407 	}
  3340 
  3408 
  3341 	$link_text = trim( wp_unslash( $_POST['link_text'] ) );
  3409 	$link_text = trim( wp_unslash( $_POST['link_text'] ) );
  3375 
  3443 
  3376 	wp_send_json_success( $html );
  3444 	wp_send_json_success( $html );
  3377 }
  3445 }
  3378 
  3446 
  3379 /**
  3447 /**
  3380  * Ajax handler for the Heartbeat API.
  3448  * Handles the Heartbeat API via AJAX.
  3381  *
  3449  *
  3382  * Runs when the user is logged in.
  3450  * Runs when the user is logged in.
  3383  *
  3451  *
  3384  * @since 3.6.0
  3452  * @since 3.6.0
  3385  */
  3453  */
  3462 
  3530 
  3463 	wp_send_json( $response );
  3531 	wp_send_json( $response );
  3464 }
  3532 }
  3465 
  3533 
  3466 /**
  3534 /**
  3467  * Ajax handler for getting revision diffs.
  3535  * Handles getting revision diffs via AJAX.
  3468  *
  3536  *
  3469  * @since 3.6.0
  3537  * @since 3.6.0
  3470  */
  3538  */
  3471 function wp_ajax_get_revision_diffs() {
  3539 function wp_ajax_get_revision_diffs() {
  3472 	require ABSPATH . 'wp-admin/includes/revision.php';
  3540 	require ABSPATH . 'wp-admin/includes/revision.php';
  3485 	if ( ! $revisions ) {
  3553 	if ( ! $revisions ) {
  3486 		wp_send_json_error();
  3554 		wp_send_json_error();
  3487 	}
  3555 	}
  3488 
  3556 
  3489 	$return = array();
  3557 	$return = array();
  3490 	set_time_limit( 0 );
  3558 
       
  3559 	if ( function_exists( 'set_time_limit' ) ) {
       
  3560 		set_time_limit( 0 );
       
  3561 	}
  3491 
  3562 
  3492 	foreach ( $_REQUEST['compare'] as $compare_key ) {
  3563 	foreach ( $_REQUEST['compare'] as $compare_key ) {
  3493 		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
  3564 		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
  3494 
  3565 
  3495 		$return[] = array(
  3566 		$return[] = array(
  3499 	}
  3570 	}
  3500 	wp_send_json_success( $return );
  3571 	wp_send_json_success( $return );
  3501 }
  3572 }
  3502 
  3573 
  3503 /**
  3574 /**
  3504  * Ajax handler for auto-saving the selected color scheme for
  3575  * Handles auto-saving the selected color scheme for
  3505  * a user's own profile.
  3576  * a user's own profile via AJAX.
  3506  *
  3577  *
  3507  * @since 3.8.0
  3578  * @since 3.8.0
  3508  *
  3579  *
  3509  * @global array $_wp_admin_css_colors
  3580  * @global array $_wp_admin_css_colors
  3510  */
  3581  */
  3529 		)
  3600 		)
  3530 	);
  3601 	);
  3531 }
  3602 }
  3532 
  3603 
  3533 /**
  3604 /**
  3534  * Ajax handler for getting themes from themes_api().
  3605  * Handles getting themes from themes_api() via AJAX.
  3535  *
  3606  *
  3536  * @since 3.9.0
  3607  * @since 3.9.0
  3537  *
  3608  *
  3538  * @global array $themes_allowedtags
  3609  * @global array $themes_allowedtags
  3539  * @global array $theme_field_defaults
  3610  * @global array $theme_field_defaults
  3660 
  3731 
  3661 	wp_send_json_success( $api );
  3732 	wp_send_json_success( $api );
  3662 }
  3733 }
  3663 
  3734 
  3664 /**
  3735 /**
  3665  * Apply [embed] Ajax handlers to a string.
  3736  * Applies [embed] Ajax handlers to a string.
  3666  *
  3737  *
  3667  * @since 4.0.0
  3738  * @since 4.0.0
  3668  *
  3739  *
  3669  * @global WP_Post    $post       Global post object.
  3740  * @global WP_Post    $post          Global post object.
  3670  * @global WP_Embed   $wp_embed   Embed API instance.
  3741  * @global WP_Embed   $wp_embed      WordPress Embed object.
  3671  * @global WP_Scripts $wp_scripts
  3742  * @global WP_Scripts $wp_scripts
  3672  * @global int        $content_width
  3743  * @global int        $content_width
  3673  */
  3744  */
  3674 function wp_ajax_parse_embed() {
  3745 function wp_ajax_parse_embed() {
  3675 	global $post, $wp_embed, $content_width;
  3746 	global $post, $wp_embed, $content_width;
  3714 		 * their post meta caches. See WP_Embed::cache_oembed().
  3785 		 * their post meta caches. See WP_Embed::cache_oembed().
  3715 		 */
  3786 		 */
  3716 		$wp_embed->usecache = false;
  3787 		$wp_embed->usecache = false;
  3717 	}
  3788 	}
  3718 
  3789 
  3719 	if ( is_ssl() && 0 === strpos( $url, 'http://' ) ) {
  3790 	if ( is_ssl() && str_starts_with( $url, 'http://' ) ) {
  3720 		// Admin is ssl and the user pasted non-ssl URL.
  3791 		/*
  3721 		// Check if the provider supports ssl embeds and use that for the preview.
  3792 		 * Admin is ssl and the user pasted non-ssl URL.
       
  3793 		 * Check if the provider supports ssl embeds and use that for the preview.
       
  3794 		 */
  3722 		$ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode );
  3795 		$ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode );
  3723 		$parsed        = $wp_embed->run_shortcode( $ssl_shortcode );
  3796 		$parsed        = $wp_embed->run_shortcode( $ssl_shortcode );
  3724 
  3797 
  3725 		if ( ! $parsed ) {
  3798 		if ( ! $parsed ) {
  3726 			$no_ssl_support = true;
  3799 			$no_ssl_support = true;
  3787 	$return = array(
  3860 	$return = array(
  3788 		'body' => $parsed,
  3861 		'body' => $parsed,
  3789 		'attr' => $wp_embed->last_attr,
  3862 		'attr' => $wp_embed->last_attr,
  3790 	);
  3863 	);
  3791 
  3864 
  3792 	if ( strpos( $parsed, 'class="wp-embedded-content' ) ) {
  3865 	if ( str_contains( $parsed, 'class="wp-embedded-content' ) ) {
  3793 		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
  3866 		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
  3794 			$script_src = includes_url( 'js/wp-embed.js' );
  3867 			$script_src = includes_url( 'js/wp-embed.js' );
  3795 		} else {
  3868 		} else {
  3796 			$script_src = includes_url( 'js/wp-embed.min.js' );
  3869 			$script_src = includes_url( 'js/wp-embed.min.js' );
  3797 		}
  3870 		}
  3816 		wp_send_json_error();
  3889 		wp_send_json_error();
  3817 	}
  3890 	}
  3818 
  3891 
  3819 	$shortcode = wp_unslash( $_POST['shortcode'] );
  3892 	$shortcode = wp_unslash( $_POST['shortcode'] );
  3820 
  3893 
       
  3894 	// Only process previews for media related shortcodes:
       
  3895 	$found_shortcodes = get_shortcode_tags_in_content( $shortcode );
       
  3896 	$media_shortcodes = array(
       
  3897 		'audio',
       
  3898 		'embed',
       
  3899 		'playlist',
       
  3900 		'video',
       
  3901 		'gallery',
       
  3902 	);
       
  3903 
       
  3904 	$other_shortcodes = array_diff( $found_shortcodes, $media_shortcodes );
       
  3905 
       
  3906 	if ( ! empty( $other_shortcodes ) ) {
       
  3907 		wp_send_json_error();
       
  3908 	}
       
  3909 
  3821 	if ( ! empty( $_POST['post_ID'] ) ) {
  3910 	if ( ! empty( $_POST['post_ID'] ) ) {
  3822 		$post = get_post( (int) $_POST['post_ID'] );
  3911 		$post = get_post( (int) $_POST['post_ID'] );
  3823 	}
  3912 	}
  3824 
  3913 
  3825 	// The embed shortcode requires a post.
  3914 	// The embed shortcode requires a post.
  3826 	if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3915 	if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3827 		if ( 'embed' === $shortcode ) {
  3916 		if ( in_array( 'embed', $found_shortcodes, true ) ) {
  3828 			wp_send_json_error();
  3917 			wp_send_json_error();
  3829 		}
  3918 		}
  3830 	} else {
  3919 	} else {
  3831 		setup_postdata( $post );
  3920 		setup_postdata( $post );
  3832 	}
  3921 	}
  3872 		)
  3961 		)
  3873 	);
  3962 	);
  3874 }
  3963 }
  3875 
  3964 
  3876 /**
  3965 /**
  3877  * Ajax handler for destroying multiple open sessions for a user.
  3966  * Handles destroying multiple open sessions for a user via AJAX.
  3878  *
  3967  *
  3879  * @since 4.1.0
  3968  * @since 4.1.0
  3880  */
  3969  */
  3881 function wp_ajax_destroy_sessions() {
  3970 function wp_ajax_destroy_sessions() {
  3882 	$user = get_userdata( (int) $_POST['user_id'] );
  3971 	$user = get_userdata( (int) $_POST['user_id'] );
  3910 
  3999 
  3911 	wp_send_json_success( array( 'message' => $message ) );
  4000 	wp_send_json_success( array( 'message' => $message ) );
  3912 }
  4001 }
  3913 
  4002 
  3914 /**
  4003 /**
  3915  * Ajax handler for cropping an image.
  4004  * Handles cropping an image via AJAX.
  3916  *
  4005  *
  3917  * @since 4.3.0
  4006  * @since 4.3.0
  3918  */
  4007  */
  3919 function wp_ajax_crop_image() {
  4008 function wp_ajax_crop_image() {
  3920 	$attachment_id = absint( $_POST['id'] );
  4009 	$attachment_id = absint( $_POST['id'] );
  3937 		case 'site-icon':
  4026 		case 'site-icon':
  3938 			require_once ABSPATH . 'wp-admin/includes/class-wp-site-icon.php';
  4027 			require_once ABSPATH . 'wp-admin/includes/class-wp-site-icon.php';
  3939 			$wp_site_icon = new WP_Site_Icon();
  4028 			$wp_site_icon = new WP_Site_Icon();
  3940 
  4029 
  3941 			// Skip creating a new attachment if the attachment is a Site Icon.
  4030 			// Skip creating a new attachment if the attachment is a Site Icon.
  3942 			if ( get_post_meta( $attachment_id, '_wp_attachment_context', true ) == $context ) {
  4031 			if ( get_post_meta( $attachment_id, '_wp_attachment_context', true ) === $context ) {
  3943 
  4032 
  3944 				// Delete the temporary cropped file, we don't need it.
  4033 				// Delete the temporary cropped file, we don't need it.
  3945 				wp_delete_file( $cropped );
  4034 				wp_delete_file( $cropped );
  3946 
  4035 
  3947 				// Additional sizes in wp_prepare_attachment_for_js().
  4036 				// Additional sizes in wp_prepare_attachment_for_js().
  3948 				add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
  4037 				add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
  3949 				break;
  4038 				break;
  3950 			}
  4039 			}
  3951 
  4040 
  3952 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  4041 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  3953 			$cropped    = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  4042 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3954 			$attachment = $wp_site_icon->create_attachment_object( $cropped, $attachment_id );
  4043 
  3955 			unset( $attachment['ID'] );
  4044 			// Copy attachment properties.
       
  4045 			$attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context );
  3956 
  4046 
  3957 			// Update the attachment.
  4047 			// Update the attachment.
  3958 			add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
  4048 			add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
  3959 			$attachment_id = $wp_site_icon->insert_attachment( $attachment, $cropped );
  4049 			$attachment_id = $wp_site_icon->insert_attachment( $attachment, $cropped );
  3960 			remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
  4050 			remove_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) );
  3978 			do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
  4068 			do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
  3979 
  4069 
  3980 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  4070 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  3981 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  4071 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3982 
  4072 
  3983 			$parent_url      = wp_get_attachment_url( $attachment_id );
  4073 			// Copy attachment properties.
  3984 			$parent_basename = wp_basename( $parent_url );
  4074 			$attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context );
  3985 			$url             = str_replace( $parent_basename, wp_basename( $cropped ), $parent_url );
       
  3986 
       
  3987 			$size       = wp_getimagesize( $cropped );
       
  3988 			$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
       
  3989 
       
  3990 			// Get the original image's post to pre-populate the cropped image.
       
  3991 			$original_attachment  = get_post( $attachment_id );
       
  3992 			$sanitized_post_title = sanitize_file_name( $original_attachment->post_title );
       
  3993 			$use_original_title   = (
       
  3994 				( '' !== trim( $original_attachment->post_title ) ) &&
       
  3995 				/*
       
  3996 				 * Check if the original image has a title other than the "filename" default,
       
  3997 				 * meaning the image had a title when originally uploaded or its title was edited.
       
  3998 				 */
       
  3999 				( $parent_basename !== $sanitized_post_title ) &&
       
  4000 				( pathinfo( $parent_basename, PATHINFO_FILENAME ) !== $sanitized_post_title )
       
  4001 			);
       
  4002 			$use_original_description = ( '' !== trim( $original_attachment->post_content ) );
       
  4003 
       
  4004 			$attachment = array(
       
  4005 				'post_title'     => $use_original_title ? $original_attachment->post_title : wp_basename( $cropped ),
       
  4006 				'post_content'   => $use_original_description ? $original_attachment->post_content : $url,
       
  4007 				'post_mime_type' => $image_type,
       
  4008 				'guid'           => $url,
       
  4009 				'context'        => $context,
       
  4010 			);
       
  4011 
       
  4012 			// Copy the image caption attribute (post_excerpt field) from the original image.
       
  4013 			if ( '' !== trim( $original_attachment->post_excerpt ) ) {
       
  4014 				$attachment['post_excerpt'] = $original_attachment->post_excerpt;
       
  4015 			}
       
  4016 
       
  4017 			// Copy the image alt text attribute from the original image.
       
  4018 			if ( '' !== trim( $original_attachment->_wp_attachment_image_alt ) ) {
       
  4019 				$attachment['meta_input'] = array(
       
  4020 					'_wp_attachment_image_alt' => wp_slash( $original_attachment->_wp_attachment_image_alt ),
       
  4021 				);
       
  4022 			}
       
  4023 
  4075 
  4024 			$attachment_id = wp_insert_attachment( $attachment, $cropped );
  4076 			$attachment_id = wp_insert_attachment( $attachment, $cropped );
  4025 			$metadata      = wp_generate_attachment_metadata( $attachment_id, $cropped );
  4077 			$metadata      = wp_generate_attachment_metadata( $attachment_id, $cropped );
  4026 
  4078 
  4027 			/**
  4079 			/**
  4049 
  4101 
  4050 	wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
  4102 	wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
  4051 }
  4103 }
  4052 
  4104 
  4053 /**
  4105 /**
  4054  * Ajax handler for generating a password.
  4106  * Handles generating a password via AJAX.
  4055  *
  4107  *
  4056  * @since 4.4.0
  4108  * @since 4.4.0
  4057  */
  4109  */
  4058 function wp_ajax_generate_password() {
  4110 function wp_ajax_generate_password() {
  4059 	wp_send_json_success( wp_generate_password( 24 ) );
  4111 	wp_send_json_success( wp_generate_password( 24 ) );
  4060 }
  4112 }
  4061 
  4113 
  4062 /**
  4114 /**
  4063  * Ajax handler for generating a password in the no-privilege context.
  4115  * Handles generating a password in the no-privilege context via AJAX.
  4064  *
  4116  *
  4065  * @since 5.7.0
  4117  * @since 5.7.0
  4066  */
  4118  */
  4067 function wp_ajax_nopriv_generate_password() {
  4119 function wp_ajax_nopriv_generate_password() {
  4068 	wp_send_json_success( wp_generate_password( 24 ) );
  4120 	wp_send_json_success( wp_generate_password( 24 ) );
  4069 }
  4121 }
  4070 
  4122 
  4071 /**
  4123 /**
  4072  * Ajax handler for saving the user's WordPress.org username.
  4124  * Handles saving the user's WordPress.org username via AJAX.
  4073  *
  4125  *
  4074  * @since 4.4.0
  4126  * @since 4.4.0
  4075  */
  4127  */
  4076 function wp_ajax_save_wporg_username() {
  4128 function wp_ajax_save_wporg_username() {
  4077 	if ( ! current_user_can( 'install_themes' ) && ! current_user_can( 'install_plugins' ) ) {
  4129 	if ( ! current_user_can( 'install_themes' ) && ! current_user_can( 'install_plugins' ) ) {
  4088 
  4140 
  4089 	wp_send_json_success( update_user_meta( get_current_user_id(), 'wporg_favorites', $username ) );
  4141 	wp_send_json_success( update_user_meta( get_current_user_id(), 'wporg_favorites', $username ) );
  4090 }
  4142 }
  4091 
  4143 
  4092 /**
  4144 /**
  4093  * Ajax handler for installing a theme.
  4145  * Handles installing a theme via AJAX.
  4094  *
  4146  *
  4095  * @since 4.6.0
  4147  * @since 4.6.0
  4096  *
  4148  *
  4097  * @see Theme_Upgrader
  4149  * @see Theme_Upgrader
  4098  *
  4150  *
  4122 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' );
  4174 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' );
  4123 		wp_send_json_error( $status );
  4175 		wp_send_json_error( $status );
  4124 	}
  4176 	}
  4125 
  4177 
  4126 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4178 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4127 	include_once ABSPATH . 'wp-admin/includes/theme.php';
  4179 	require_once ABSPATH . 'wp-admin/includes/theme.php';
  4128 
  4180 
  4129 	$api = themes_api(
  4181 	$api = themes_api(
  4130 		'theme_information',
  4182 		'theme_information',
  4131 		array(
  4183 		array(
  4132 			'slug'   => $slug,
  4184 			'slug'   => $slug,
  4214 	 */
  4266 	 */
  4215 	wp_send_json_success( $status );
  4267 	wp_send_json_success( $status );
  4216 }
  4268 }
  4217 
  4269 
  4218 /**
  4270 /**
  4219  * Ajax handler for updating a theme.
  4271  * Handles updating a theme via AJAX.
  4220  *
  4272  *
  4221  * @since 4.6.0
  4273  * @since 4.6.0
  4222  *
  4274  *
  4223  * @see Theme_Upgrader
  4275  * @see Theme_Upgrader
  4224  *
  4276  *
  4309 	$status['errorMessage'] = __( 'Theme update failed.' );
  4361 	$status['errorMessage'] = __( 'Theme update failed.' );
  4310 	wp_send_json_error( $status );
  4362 	wp_send_json_error( $status );
  4311 }
  4363 }
  4312 
  4364 
  4313 /**
  4365 /**
  4314  * Ajax handler for deleting a theme.
  4366  * Handles deleting a theme via AJAX.
  4315  *
  4367  *
  4316  * @since 4.6.0
  4368  * @since 4.6.0
  4317  *
  4369  *
  4318  * @see delete_theme()
  4370  * @see delete_theme()
  4319  *
  4371  *
  4367 		}
  4419 		}
  4368 
  4420 
  4369 		wp_send_json_error( $status );
  4421 		wp_send_json_error( $status );
  4370 	}
  4422 	}
  4371 
  4423 
  4372 	include_once ABSPATH . 'wp-admin/includes/theme.php';
  4424 	require_once ABSPATH . 'wp-admin/includes/theme.php';
  4373 
  4425 
  4374 	$result = delete_theme( $stylesheet );
  4426 	$result = delete_theme( $stylesheet );
  4375 
  4427 
  4376 	if ( is_wp_error( $result ) ) {
  4428 	if ( is_wp_error( $result ) ) {
  4377 		$status['errorMessage'] = $result->get_error_message();
  4429 		$status['errorMessage'] = $result->get_error_message();
  4383 
  4435 
  4384 	wp_send_json_success( $status );
  4436 	wp_send_json_success( $status );
  4385 }
  4437 }
  4386 
  4438 
  4387 /**
  4439 /**
  4388  * Ajax handler for installing a plugin.
  4440  * Handles installing a plugin via AJAX.
  4389  *
  4441  *
  4390  * @since 4.6.0
  4442  * @since 4.6.0
  4391  *
  4443  *
  4392  * @see Plugin_Upgrader
  4444  * @see Plugin_Upgrader
  4393  *
  4445  *
  4415 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' );
  4467 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' );
  4416 		wp_send_json_error( $status );
  4468 		wp_send_json_error( $status );
  4417 	}
  4469 	}
  4418 
  4470 
  4419 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4471 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4420 	include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
  4472 	require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
  4421 
  4473 
  4422 	$api = plugins_api(
  4474 	$api = plugins_api(
  4423 		'plugin_information',
  4475 		'plugin_information',
  4424 		array(
  4476 		array(
  4425 			'slug'   => sanitize_key( wp_unslash( $_POST['slug'] ) ),
  4477 			'slug'   => sanitize_key( wp_unslash( $_POST['slug'] ) ),
  4492 
  4544 
  4493 	wp_send_json_success( $status );
  4545 	wp_send_json_success( $status );
  4494 }
  4546 }
  4495 
  4547 
  4496 /**
  4548 /**
  4497  * Ajax handler for updating a plugin.
  4549  * Handles activating a plugin via AJAX.
       
  4550  *
       
  4551  * @since 6.5.0
       
  4552  */
       
  4553 function wp_ajax_activate_plugin() {
       
  4554 	check_ajax_referer( 'updates' );
       
  4555 
       
  4556 	if ( empty( $_POST['name'] ) || empty( $_POST['slug'] ) || empty( $_POST['plugin'] ) ) {
       
  4557 		wp_send_json_error(
       
  4558 			array(
       
  4559 				'slug'         => '',
       
  4560 				'pluginName'   => '',
       
  4561 				'plugin'       => '',
       
  4562 				'errorCode'    => 'no_plugin_specified',
       
  4563 				'errorMessage' => __( 'No plugin specified.' ),
       
  4564 			)
       
  4565 		);
       
  4566 	}
       
  4567 
       
  4568 	$status = array(
       
  4569 		'activate'   => 'plugin',
       
  4570 		'slug'       => wp_unslash( $_POST['slug'] ),
       
  4571 		'pluginName' => wp_unslash( $_POST['name'] ),
       
  4572 		'plugin'     => wp_unslash( $_POST['plugin'] ),
       
  4573 	);
       
  4574 
       
  4575 	if ( ! current_user_can( 'activate_plugin', $status['plugin'] ) ) {
       
  4576 		$status['errorMessage'] = __( 'Sorry, you are not allowed to activate plugins on this site.' );
       
  4577 		wp_send_json_error( $status );
       
  4578 	}
       
  4579 
       
  4580 	if ( is_plugin_active( $status['plugin'] ) ) {
       
  4581 		$status['errorMessage'] = sprintf(
       
  4582 			/* translators: %s: Plugin name. */
       
  4583 			__( '%s is already active.' ),
       
  4584 			$status['pluginName']
       
  4585 		);
       
  4586 	}
       
  4587 
       
  4588 	$activated = activate_plugin( $status['plugin'] );
       
  4589 
       
  4590 	if ( is_wp_error( $activated ) ) {
       
  4591 		$status['errorMessage'] = $activated->get_error_message();
       
  4592 		wp_send_json_error( $status );
       
  4593 	}
       
  4594 
       
  4595 	wp_send_json_success( $status );
       
  4596 }
       
  4597 
       
  4598 /**
       
  4599  * Handles updating a plugin via AJAX.
  4498  *
  4600  *
  4499  * @since 4.2.0
  4601  * @since 4.2.0
  4500  *
  4602  *
  4501  * @see Plugin_Upgrader
  4603  * @see Plugin_Upgrader
  4502  *
  4604  *
  4600 	$status['errorMessage'] = __( 'Plugin update failed.' );
  4702 	$status['errorMessage'] = __( 'Plugin update failed.' );
  4601 	wp_send_json_error( $status );
  4703 	wp_send_json_error( $status );
  4602 }
  4704 }
  4603 
  4705 
  4604 /**
  4706 /**
  4605  * Ajax handler for deleting a plugin.
  4707  * Handles deleting a plugin via AJAX.
  4606  *
  4708  *
  4607  * @since 4.6.0
  4709  * @since 4.6.0
  4608  *
  4710  *
  4609  * @see delete_plugins()
  4711  * @see delete_plugins()
  4610  *
  4712  *
  4677 
  4779 
  4678 	wp_send_json_success( $status );
  4780 	wp_send_json_success( $status );
  4679 }
  4781 }
  4680 
  4782 
  4681 /**
  4783 /**
  4682  * Ajax handler for searching plugins.
  4784  * Handles searching plugins via AJAX.
  4683  *
  4785  *
  4684  * @since 4.6.0
  4786  * @since 4.6.0
  4685  *
  4787  *
  4686  * @global string $s Search term.
  4788  * @global string $s Search term.
  4687  */
  4789  */
  4734 
  4836 
  4735 	wp_send_json_success( $status );
  4837 	wp_send_json_success( $status );
  4736 }
  4838 }
  4737 
  4839 
  4738 /**
  4840 /**
  4739  * Ajax handler for searching plugins to install.
  4841  * Handles searching plugins to install via AJAX.
  4740  *
  4842  *
  4741  * @since 4.6.0
  4843  * @since 4.6.0
  4742  */
  4844  */
  4743 function wp_ajax_search_install_plugins() {
  4845 function wp_ajax_search_install_plugins() {
  4744 	check_ajax_referer( 'updates' );
  4846 	check_ajax_referer( 'updates' );
  4784 
  4886 
  4785 	wp_send_json_success( $status );
  4887 	wp_send_json_success( $status );
  4786 }
  4888 }
  4787 
  4889 
  4788 /**
  4890 /**
  4789  * Ajax handler for editing a theme or plugin file.
  4891  * Handles editing a theme or plugin file via AJAX.
  4790  *
  4892  *
  4791  * @since 4.9.0
  4893  * @since 4.9.0
  4792  *
  4894  *
  4793  * @see wp_edit_theme_plugin_file()
  4895  * @see wp_edit_theme_plugin_file()
  4794  */
  4896  */
  4813 		);
  4915 		);
  4814 	}
  4916 	}
  4815 }
  4917 }
  4816 
  4918 
  4817 /**
  4919 /**
  4818  * Ajax handler for exporting a user's personal data.
  4920  * Handles exporting a user's personal data via AJAX.
  4819  *
  4921  *
  4820  * @since 4.9.6
  4922  * @since 4.9.6
  4821  */
  4923  */
  4822 function wp_ajax_wp_privacy_export_personal_data() {
  4924 function wp_ajax_wp_privacy_export_personal_data() {
  4823 
  4925 
  4873 	 *
  4975 	 *
  4874 	 *     @type array ...$0 {
  4976 	 *     @type array ...$0 {
  4875 	 *         Array of personal data exporters.
  4977 	 *         Array of personal data exporters.
  4876 	 *
  4978 	 *
  4877 	 *         @type callable $callback               Callable exporter function that accepts an
  4979 	 *         @type callable $callback               Callable exporter function that accepts an
  4878 	 *                                                email address and a page and returns an array
  4980 	 *                                                email address and a page number and returns an
  4879 	 *                                                of name => value pairs of personal data.
  4981 	 *                                                array of name => value pairs of personal data.
  4880 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the
  4982 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the
  4881 	 *                                                exporter.
  4983 	 *                                                exporter.
  4882 	 *     }
  4984 	 *     }
  4883 	 * }
  4985 	 * }
  4884 	 */
  4986 	 */
  4985 	 *
  5087 	 *
  4986 	 * Allows the export response to be consumed by destinations in addition to Ajax.
  5088 	 * Allows the export response to be consumed by destinations in addition to Ajax.
  4987 	 *
  5089 	 *
  4988 	 * @since 4.9.6
  5090 	 * @since 4.9.6
  4989 	 *
  5091 	 *
  4990 	 * @param array  $response        The personal data for the given exporter and page.
  5092 	 * @param array  $response        The personal data for the given exporter and page number.
  4991 	 * @param int    $exporter_index  The index of the exporter that provided this data.
  5093 	 * @param int    $exporter_index  The index of the exporter that provided this data.
  4992 	 * @param string $email_address   The email address associated with this personal data.
  5094 	 * @param string $email_address   The email address associated with this personal data.
  4993 	 * @param int    $page            The page for this response.
  5095 	 * @param int    $page            The page number for this response.
  4994 	 * @param int    $request_id      The privacy request post ID associated with this request.
  5096 	 * @param int    $request_id      The privacy request post ID associated with this request.
  4995 	 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
  5097 	 * @param bool   $send_as_email   Whether the final results of the export should be emailed to the user.
  4996 	 * @param string $exporter_key    The key (slug) of the exporter that provided this data.
  5098 	 * @param string $exporter_key    The key (slug) of the exporter that provided this data.
  4997 	 */
  5099 	 */
  4998 	$response = apply_filters( 'wp_privacy_personal_data_export_page', $response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key );
  5100 	$response = apply_filters( 'wp_privacy_personal_data_export_page', $response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key );
  5003 
  5105 
  5004 	wp_send_json_success( $response );
  5106 	wp_send_json_success( $response );
  5005 }
  5107 }
  5006 
  5108 
  5007 /**
  5109 /**
  5008  * Ajax handler for erasing personal data.
  5110  * Handles erasing personal data via AJAX.
  5009  *
  5111  *
  5010  * @since 4.9.6
  5112  * @since 4.9.6
  5011  */
  5113  */
  5012 function wp_ajax_wp_privacy_erase_personal_data() {
  5114 function wp_ajax_wp_privacy_erase_personal_data() {
  5013 
  5115 
  5062 	 *     An array of callable erasers of personal data. Default empty array.
  5164 	 *     An array of callable erasers of personal data. Default empty array.
  5063 	 *
  5165 	 *
  5064 	 *     @type array ...$0 {
  5166 	 *     @type array ...$0 {
  5065 	 *         Array of personal data exporters.
  5167 	 *         Array of personal data exporters.
  5066 	 *
  5168 	 *
  5067 	 *         @type callable $callback               Callable eraser that accepts an email address and
  5169 	 *         @type callable $callback               Callable eraser that accepts an email address and a page
  5068 	 *                                                a page and returns an array with boolean values for
  5170 	 *                                                number, and returns an array with boolean values for
  5069 	 *                                                whether items were removed or retained and any messages
  5171 	 *                                                whether items were removed or retained and any messages
  5070 	 *                                                from the eraser, as well as if additional pages are
  5172 	 *                                                from the eraser, as well as if additional pages are
  5071 	 *                                                available.
  5173 	 *                                                available.
  5072 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the eraser.
  5174 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the eraser.
  5073 	 *     }
  5175 	 *     }
  5215 	 *
  5317 	 *
  5216 	 * Allows the erasure response to be consumed by destinations in addition to Ajax.
  5318 	 * Allows the erasure response to be consumed by destinations in addition to Ajax.
  5217 	 *
  5319 	 *
  5218 	 * @since 4.9.6
  5320 	 * @since 4.9.6
  5219 	 *
  5321 	 *
  5220 	 * @param array  $response        The personal data for the given exporter and page.
  5322 	 * @param array  $response        {
       
  5323 	 *     The personal data for the given exporter and page number.
       
  5324 	 *
       
  5325 	 *     @type bool     $items_removed  Whether items were actually removed or not.
       
  5326 	 *     @type bool     $items_retained Whether items were retained or not.
       
  5327 	 *     @type string[] $messages       An array of messages to add to the personal data export file.
       
  5328 	 *     @type bool     $done           Whether the eraser is finished or not.
       
  5329 	 * }
  5221 	 * @param int    $eraser_index    The index of the eraser that provided this data.
  5330 	 * @param int    $eraser_index    The index of the eraser that provided this data.
  5222 	 * @param string $email_address   The email address associated with this personal data.
  5331 	 * @param string $email_address   The email address associated with this personal data.
  5223 	 * @param int    $page            The page for this response.
  5332 	 * @param int    $page            The page number for this response.
  5224 	 * @param int    $request_id      The privacy request post ID associated with this request.
  5333 	 * @param int    $request_id      The privacy request post ID associated with this request.
  5225 	 * @param string $eraser_key      The key (slug) of the eraser that provided this data.
  5334 	 * @param string $eraser_key      The key (slug) of the eraser that provided this data.
  5226 	 */
  5335 	 */
  5227 	$response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id, $eraser_key );
  5336 	$response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id, $eraser_key );
  5228 
  5337 
  5232 
  5341 
  5233 	wp_send_json_success( $response );
  5342 	wp_send_json_success( $response );
  5234 }
  5343 }
  5235 
  5344 
  5236 /**
  5345 /**
  5237  * Ajax handler for site health checks on server communication.
  5346  * Handles site health checks on server communication via AJAX.
  5238  *
  5347  *
  5239  * @since 5.2.0
  5348  * @since 5.2.0
  5240  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_dotorg_communication()
  5349  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_dotorg_communication()
  5241  * @see WP_REST_Site_Health_Controller::test_dotorg_communication()
  5350  * @see WP_REST_Site_Health_Controller::test_dotorg_communication()
  5242  */
  5351  */
  5265 	$site_health = WP_Site_Health::get_instance();
  5374 	$site_health = WP_Site_Health::get_instance();
  5266 	wp_send_json_success( $site_health->get_test_dotorg_communication() );
  5375 	wp_send_json_success( $site_health->get_test_dotorg_communication() );
  5267 }
  5376 }
  5268 
  5377 
  5269 /**
  5378 /**
  5270  * Ajax handler for site health checks on background updates.
  5379  * Handles site health checks on background updates via AJAX.
  5271  *
  5380  *
  5272  * @since 5.2.0
  5381  * @since 5.2.0
  5273  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_background_updates()
  5382  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_background_updates()
  5274  * @see WP_REST_Site_Health_Controller::test_background_updates()
  5383  * @see WP_REST_Site_Health_Controller::test_background_updates()
  5275  */
  5384  */
  5298 	$site_health = WP_Site_Health::get_instance();
  5407 	$site_health = WP_Site_Health::get_instance();
  5299 	wp_send_json_success( $site_health->get_test_background_updates() );
  5408 	wp_send_json_success( $site_health->get_test_background_updates() );
  5300 }
  5409 }
  5301 
  5410 
  5302 /**
  5411 /**
  5303  * Ajax handler for site health checks on loopback requests.
  5412  * Handles site health checks on loopback requests via AJAX.
  5304  *
  5413  *
  5305  * @since 5.2.0
  5414  * @since 5.2.0
  5306  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_loopback_requests()
  5415  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::test_loopback_requests()
  5307  * @see WP_REST_Site_Health_Controller::test_loopback_requests()
  5416  * @see WP_REST_Site_Health_Controller::test_loopback_requests()
  5308  */
  5417  */
  5331 	$site_health = WP_Site_Health::get_instance();
  5440 	$site_health = WP_Site_Health::get_instance();
  5332 	wp_send_json_success( $site_health->get_test_loopback_requests() );
  5441 	wp_send_json_success( $site_health->get_test_loopback_requests() );
  5333 }
  5442 }
  5334 
  5443 
  5335 /**
  5444 /**
  5336  * Ajax handler for site health check to update the result status.
  5445  * Handles site health check to update the result status via AJAX.
  5337  *
  5446  *
  5338  * @since 5.2.0
  5447  * @since 5.2.0
  5339  */
  5448  */
  5340 function wp_ajax_health_check_site_status_result() {
  5449 function wp_ajax_health_check_site_status_result() {
  5341 	check_ajax_referer( 'health-check-site-status-result' );
  5450 	check_ajax_referer( 'health-check-site-status-result' );
  5348 
  5457 
  5349 	wp_send_json_success();
  5458 	wp_send_json_success();
  5350 }
  5459 }
  5351 
  5460 
  5352 /**
  5461 /**
  5353  * Ajax handler for site health check to get directories and database sizes.
  5462  * Handles site health check to get directories and database sizes via AJAX.
  5354  *
  5463  *
  5355  * @since 5.2.0
  5464  * @since 5.2.0
  5356  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::get_directory_sizes()
  5465  * @deprecated 5.6.0 Use WP_REST_Site_Health_Controller::get_directory_sizes()
  5357  * @see WP_REST_Site_Health_Controller::get_directory_sizes()
  5466  * @see WP_REST_Site_Health_Controller::get_directory_sizes()
  5358  */
  5467  */
  5414 
  5523 
  5415 	wp_send_json_success( $all_sizes );
  5524 	wp_send_json_success( $all_sizes );
  5416 }
  5525 }
  5417 
  5526 
  5418 /**
  5527 /**
  5419  * Ajax handler to renew the REST API nonce.
  5528  * Handles renewing the REST API nonce via AJAX.
  5420  *
  5529  *
  5421  * @since 5.3.0
  5530  * @since 5.3.0
  5422  */
  5531  */
  5423 function wp_ajax_rest_nonce() {
  5532 function wp_ajax_rest_nonce() {
  5424 	exit( wp_create_nonce( 'wp_rest' ) );
  5533 	exit( wp_create_nonce( 'wp_rest' ) );
  5425 }
  5534 }
  5426 
  5535 
  5427 /**
  5536 /**
  5428  * Ajax handler to enable or disable plugin and theme auto-updates.
  5537  * Handles enabling or disable plugin and theme auto-updates via AJAX.
  5429  *
  5538  *
  5430  * @since 5.5.0
  5539  * @since 5.5.0
  5431  */
  5540  */
  5432 function wp_ajax_toggle_auto_updates() {
  5541 function wp_ajax_toggle_auto_updates() {
  5433 	check_ajax_referer( 'updates' );
  5542 	check_ajax_referer( 'updates' );
  5493 
  5602 
  5494 	wp_send_json_success();
  5603 	wp_send_json_success();
  5495 }
  5604 }
  5496 
  5605 
  5497 /**
  5606 /**
  5498  * Ajax handler sends a password reset link.
  5607  * Handles sending a password reset link via AJAX.
  5499  *
  5608  *
  5500  * @since 5.7.0
  5609  * @since 5.7.0
  5501  */
  5610  */
  5502 function wp_ajax_send_password_reset() {
  5611 function wp_ajax_send_password_reset() {
  5503 
  5612