wp/wp-admin/includes/ajax-actions.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    20  * @since 3.6.0
    20  * @since 3.6.0
    21  */
    21  */
    22 function wp_ajax_nopriv_heartbeat() {
    22 function wp_ajax_nopriv_heartbeat() {
    23 	$response = array();
    23 	$response = array();
    24 
    24 
    25 	// screen_id is the same as $current_screen->id and the JS global 'pagenow'.
    25 	// 'screen_id' is the same as $current_screen->id and the JS global 'pagenow'.
    26 	if ( ! empty( $_POST['screen_id'] ) ) {
    26 	if ( ! empty( $_POST['screen_id'] ) ) {
    27 		$screen_id = sanitize_key( $_POST['screen_id'] );
    27 		$screen_id = sanitize_key( $_POST['screen_id'] );
    28 	} else {
    28 	} else {
    29 		$screen_id = 'front';
    29 		$screen_id = 'front';
    30 	}
    30 	}
    37 		 *
    37 		 *
    38 		 * @since 3.6.0
    38 		 * @since 3.6.0
    39 		 *
    39 		 *
    40 		 * @param array  $response  The no-priv Heartbeat response.
    40 		 * @param array  $response  The no-priv Heartbeat response.
    41 		 * @param array  $data      The $_POST data sent.
    41 		 * @param array  $data      The $_POST data sent.
    42 		 * @param string $screen_id The screen id.
    42 		 * @param string $screen_id The screen ID.
    43 		 */
    43 		 */
    44 		$response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id );
    44 		$response = apply_filters( 'heartbeat_nopriv_received', $response, $data, $screen_id );
    45 	}
    45 	}
    46 
    46 
    47 	/**
    47 	/**
    48 	 * Filters Heartbeat Ajax response in no-privilege environments when no data is passed.
    48 	 * Filters Heartbeat Ajax response in no-privilege environments when no data is passed.
    49 	 *
    49 	 *
    50 	 * @since 3.6.0
    50 	 * @since 3.6.0
    51 	 *
    51 	 *
    52 	 * @param array  $response  The no-priv Heartbeat response.
    52 	 * @param array  $response  The no-priv Heartbeat response.
    53 	 * @param string $screen_id The screen id.
    53 	 * @param string $screen_id The screen ID.
    54 	 */
    54 	 */
    55 	$response = apply_filters( 'heartbeat_nopriv_send', $response, $screen_id );
    55 	$response = apply_filters( 'heartbeat_nopriv_send', $response, $screen_id );
    56 
    56 
    57 	/**
    57 	/**
    58 	 * Fires when Heartbeat ticks in no-privilege environments.
    58 	 * Fires when Heartbeat ticks in no-privilege environments.
    60 	 * Allows the transport to be easily replaced with long-polling.
    60 	 * Allows the transport to be easily replaced with long-polling.
    61 	 *
    61 	 *
    62 	 * @since 3.6.0
    62 	 * @since 3.6.0
    63 	 *
    63 	 *
    64 	 * @param array  $response  The no-priv Heartbeat response.
    64 	 * @param array  $response  The no-priv Heartbeat response.
    65 	 * @param string $screen_id The screen id.
    65 	 * @param string $screen_id The screen ID.
    66 	 */
    66 	 */
    67 	do_action( 'heartbeat_nopriv_tick', $response, $screen_id );
    67 	do_action( 'heartbeat_nopriv_tick', $response, $screen_id );
    68 
    68 
    69 	// Send the current time according to the server.
    69 	// Send the current time according to the server.
    70 	$response['server_time'] = time();
    70 	$response['server_time'] = time();
   109 		wp_die( 0 );
   109 		wp_die( 0 );
   110 	}
   110 	}
   111 
   111 
   112 	$taxonomy = sanitize_key( $_GET['tax'] );
   112 	$taxonomy = sanitize_key( $_GET['tax'] );
   113 	$tax      = get_taxonomy( $taxonomy );
   113 	$tax      = get_taxonomy( $taxonomy );
       
   114 
   114 	if ( ! $tax ) {
   115 	if ( ! $tax ) {
   115 		wp_die( 0 );
   116 		wp_die( 0 );
   116 	}
   117 	}
   117 
   118 
   118 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
   119 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
   123 
   124 
   124 	$comma = _x( ',', 'tag delimiter' );
   125 	$comma = _x( ',', 'tag delimiter' );
   125 	if ( ',' !== $comma ) {
   126 	if ( ',' !== $comma ) {
   126 		$s = str_replace( $comma, ',', $s );
   127 		$s = str_replace( $comma, ',', $s );
   127 	}
   128 	}
       
   129 
   128 	if ( false !== strpos( $s, ',' ) ) {
   130 	if ( false !== strpos( $s, ',' ) ) {
   129 		$s = explode( ',', $s );
   131 		$s = explode( ',', $s );
   130 		$s = $s[ count( $s ) - 1 ];
   132 		$s = $s[ count( $s ) - 1 ];
   131 	}
   133 	}
       
   134 
   132 	$s = trim( $s );
   135 	$s = trim( $s );
   133 
   136 
   134 	/**
   137 	/**
   135 	 * Filters the minimum number of characters required to fire a tag search via Ajax.
   138 	 * Filters the minimum number of characters required to fire a tag search via Ajax.
   136 	 *
   139 	 *
   144 
   147 
   145 	/*
   148 	/*
   146 	 * Require $term_search_min_chars chars for matching (default: 2)
   149 	 * Require $term_search_min_chars chars for matching (default: 2)
   147 	 * ensure it's a non-negative, non-zero integer.
   150 	 * ensure it's a non-negative, non-zero integer.
   148 	 */
   151 	 */
   149 	if ( ( $term_search_min_chars == 0 ) || ( strlen( $s ) < $term_search_min_chars ) ) {
   152 	if ( ( 0 == $term_search_min_chars ) || ( strlen( $s ) < $term_search_min_chars ) ) {
   150 		wp_die();
   153 		wp_die();
   151 	}
   154 	}
   152 
   155 
   153 	$results = get_terms(
   156 	$results = get_terms(
   154 		$taxonomy,
       
   155 		array(
   157 		array(
       
   158 			'taxonomy'   => $taxonomy,
   156 			'name__like' => $s,
   159 			'name__like' => $s,
   157 			'fields'     => 'names',
   160 			'fields'     => 'names',
   158 			'hide_empty' => false,
   161 			'hide_empty' => false,
   159 		)
   162 		)
   160 	);
   163 	);
   161 
   164 
   162 	echo join( $results, "\n" );
   165 	echo join( "\n", $results );
   163 	wp_die();
   166 	wp_die();
   164 }
   167 }
   165 
   168 
   166 /**
   169 /**
   167  * Ajax handler for compression testing.
   170  * Ajax handler for compression testing.
   171 function wp_ajax_wp_compression_test() {
   174 function wp_ajax_wp_compression_test() {
   172 	if ( ! current_user_can( 'manage_options' ) ) {
   175 	if ( ! current_user_can( 'manage_options' ) ) {
   173 		wp_die( -1 );
   176 		wp_die( -1 );
   174 	}
   177 	}
   175 
   178 
   176 	if ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' == ini_get( 'output_handler' ) ) {
   179 	if ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ) {
   177 		update_site_option( 'can_compress_scripts', 0 );
   180 		update_site_option( 'can_compress_scripts', 0 );
   178 		wp_die( 0 );
   181 		wp_die( 0 );
   179 	}
   182 	}
   180 
   183 
   181 	if ( isset( $_GET['test'] ) ) {
   184 	if ( isset( $_GET['test'] ) ) {
   191 			wp_die();
   194 			wp_die();
   192 		} elseif ( 2 == $_GET['test'] ) {
   195 		} elseif ( 2 == $_GET['test'] ) {
   193 			if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
   196 			if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
   194 				wp_die( -1 );
   197 				wp_die( -1 );
   195 			}
   198 			}
       
   199 
   196 			if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate' ) && function_exists( 'gzdeflate' ) && ! $force_gzip ) {
   200 			if ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate' ) && function_exists( 'gzdeflate' ) && ! $force_gzip ) {
   197 				header( 'Content-Encoding: deflate' );
   201 				header( 'Content-Encoding: deflate' );
   198 				$out = gzdeflate( $test_str, 1 );
   202 				$out = gzdeflate( $test_str, 1 );
   199 			} elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) && function_exists( 'gzencode' ) ) {
   203 			} elseif ( false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) && function_exists( 'gzencode' ) ) {
   200 				header( 'Content-Encoding: gzip' );
   204 				header( 'Content-Encoding: gzip' );
   201 				$out = gzencode( $test_str, 1 );
   205 				$out = gzencode( $test_str, 1 );
   202 			} else {
   206 			} else {
   203 				wp_die( -1 );
   207 				wp_die( -1 );
   204 			}
   208 			}
       
   209 
   205 			echo $out;
   210 			echo $out;
   206 			wp_die();
   211 			wp_die();
   207 		} elseif ( 'no' == $_GET['test'] ) {
   212 		} elseif ( 'no' === $_GET['test'] ) {
   208 			check_ajax_referer( 'update_can_compress_scripts' );
   213 			check_ajax_referer( 'update_can_compress_scripts' );
   209 			update_site_option( 'can_compress_scripts', 0 );
   214 			update_site_option( 'can_compress_scripts', 0 );
   210 		} elseif ( 'yes' == $_GET['test'] ) {
   215 		} elseif ( 'yes' === $_GET['test'] ) {
   211 			check_ajax_referer( 'update_can_compress_scripts' );
   216 			check_ajax_referer( 'update_can_compress_scripts' );
   212 			update_site_option( 'can_compress_scripts', 1 );
   217 			update_site_option( 'can_compress_scripts', 1 );
   213 		}
   218 		}
   214 	}
   219 	}
   215 
   220 
   227 		wp_die( -1 );
   232 		wp_die( -1 );
   228 	}
   233 	}
   229 
   234 
   230 	check_ajax_referer( "image_editor-$post_id" );
   235 	check_ajax_referer( "image_editor-$post_id" );
   231 
   236 
   232 	include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
   237 	include_once ABSPATH . 'wp-admin/includes/image-edit.php';
       
   238 
   233 	if ( ! stream_preview_image( $post_id ) ) {
   239 	if ( ! stream_preview_image( $post_id ) ) {
   234 		wp_die( -1 );
   240 		wp_die( -1 );
   235 	}
   241 	}
   236 
   242 
   237 	wp_die();
   243 	wp_die();
   264 		wp_die( -1 );
   270 		wp_die( -1 );
   265 	}
   271 	}
   266 
   272 
   267 	$return = array();
   273 	$return = array();
   268 
   274 
   269 	// Check the type of request
   275 	// Check the type of request.
   270 	// Current allowed values are `add` and `search`
   276 	// Current allowed values are `add` and `search`.
   271 	if ( isset( $_REQUEST['autocomplete_type'] ) && 'search' === $_REQUEST['autocomplete_type'] ) {
   277 	if ( isset( $_REQUEST['autocomplete_type'] ) && 'search' === $_REQUEST['autocomplete_type'] ) {
   272 		$type = $_REQUEST['autocomplete_type'];
   278 		$type = $_REQUEST['autocomplete_type'];
   273 	} else {
   279 	} else {
   274 		$type = 'add';
   280 		$type = 'add';
   275 	}
   281 	}
   276 
   282 
   277 	// Check the desired field for value
   283 	// Check the desired field for value.
   278 	// Current allowed values are `user_email` and `user_login`
   284 	// Current allowed values are `user_email` and `user_login`.
   279 	if ( isset( $_REQUEST['autocomplete_field'] ) && 'user_email' === $_REQUEST['autocomplete_field'] ) {
   285 	if ( isset( $_REQUEST['autocomplete_field'] ) && 'user_email' === $_REQUEST['autocomplete_field'] ) {
   280 		$field = $_REQUEST['autocomplete_field'];
   286 		$field = $_REQUEST['autocomplete_field'];
   281 	} else {
   287 	} else {
   282 		$field = 'user_login';
   288 		$field = 'user_login';
   283 	}
   289 	}
   284 
   290 
   285 	// Exclude current users of this blog
   291 	// Exclude current users of this blog.
   286 	if ( isset( $_REQUEST['site_id'] ) ) {
   292 	if ( isset( $_REQUEST['site_id'] ) ) {
   287 		$id = absint( $_REQUEST['site_id'] );
   293 		$id = absint( $_REQUEST['site_id'] );
   288 	} else {
   294 	} else {
   289 		$id = get_current_blog_id();
   295 		$id = get_current_blog_id();
   290 	}
   296 	}
   291 
   297 
   292 	$include_blog_users = ( $type == 'search' ? get_users(
   298 	$include_blog_users = ( 'search' === $type ? get_users(
   293 		array(
   299 		array(
   294 			'blog_id' => $id,
   300 			'blog_id' => $id,
   295 			'fields'  => 'ID',
   301 			'fields'  => 'ID',
   296 		)
   302 		)
   297 	) : array() );
   303 	) : array() );
   298 	$exclude_blog_users = ( $type == 'add' ? get_users(
   304 
       
   305 	$exclude_blog_users = ( 'add' === $type ? get_users(
   299 		array(
   306 		array(
   300 			'blog_id' => $id,
   307 			'blog_id' => $id,
   301 			'fields'  => 'ID',
   308 			'fields'  => 'ID',
   302 		)
   309 		)
   303 	) : array() );
   310 	) : array() );
   312 		)
   319 		)
   313 	);
   320 	);
   314 
   321 
   315 	foreach ( $users as $user ) {
   322 	foreach ( $users as $user ) {
   316 		$return[] = array(
   323 		$return[] = array(
   317 			/* translators: 1: user_login, 2: user_email */
   324 			/* translators: 1: User login, 2: User email address. */
   318 			'label' => sprintf( _x( '%1$s (%2$s)', 'user autocomplete result' ), $user->user_login, $user->user_email ),
   325 			'label' => sprintf( _x( '%1$s (%2$s)', 'user autocomplete result' ), $user->user_login, $user->user_email ),
   319 			'value' => $user->$field,
   326 			'value' => $user->$field,
   320 		);
   327 		);
   321 	}
   328 	}
   322 
   329 
   323 	wp_die( wp_json_encode( $return ) );
   330 	wp_die( wp_json_encode( $return ) );
   324 }
   331 }
   325 
   332 
   326 /**
   333 /**
   327  * Handles AJAX requests for community events
   334  * Handles Ajax requests for community events
   328  *
   335  *
   329  * @since 4.8.0
   336  * @since 4.8.0
   330  */
   337  */
   331 function wp_ajax_get_community_events() {
   338 function wp_ajax_get_community_events() {
   332 	require_once( ABSPATH . 'wp-admin/includes/class-wp-community-events.php' );
   339 	require_once ABSPATH . 'wp-admin/includes/class-wp-community-events.php';
   333 
   340 
   334 	check_ajax_referer( 'community_events' );
   341 	check_ajax_referer( 'community_events' );
   335 
   342 
   336 	$search         = isset( $_POST['location'] ) ? wp_unslash( $_POST['location'] ) : '';
   343 	$search         = isset( $_POST['location'] ) ? wp_unslash( $_POST['location'] ) : '';
   337 	$timezone       = isset( $_POST['timezone'] ) ? wp_unslash( $_POST['timezone'] ) : '';
   344 	$timezone       = isset( $_POST['timezone'] ) ? wp_unslash( $_POST['timezone'] ) : '';
   382  */
   389  */
   383 function wp_ajax_dashboard_widgets() {
   390 function wp_ajax_dashboard_widgets() {
   384 	require_once ABSPATH . 'wp-admin/includes/dashboard.php';
   391 	require_once ABSPATH . 'wp-admin/includes/dashboard.php';
   385 
   392 
   386 	$pagenow = $_GET['pagenow'];
   393 	$pagenow = $_GET['pagenow'];
   387 	if ( $pagenow === 'dashboard-user' || $pagenow === 'dashboard-network' || $pagenow === 'dashboard' ) {
   394 	if ( 'dashboard-user' === $pagenow || 'dashboard-network' === $pagenow || 'dashboard' === $pagenow ) {
   388 		set_current_screen( $pagenow );
   395 		set_current_screen( $pagenow );
   389 	}
   396 	}
   390 
   397 
   391 	switch ( $_GET['widget'] ) {
   398 	switch ( $_GET['widget'] ) {
   392 		case 'dashboard_primary':
   399 		case 'dashboard_primary':
   412 /**
   419 /**
   413  * Sends back current comment total and new page links if they need to be updated.
   420  * Sends back current comment total and new page links if they need to be updated.
   414  *
   421  *
   415  * Contrary to normal success Ajax response ("1"), die with time() on success.
   422  * Contrary to normal success Ajax response ("1"), die with time() on success.
   416  *
   423  *
       
   424  * @since 2.7.0
   417  * @access private
   425  * @access private
   418  * @since 2.7.0
       
   419  *
   426  *
   420  * @param int $comment_id
   427  * @param int $comment_id
   421  * @param int $delta
   428  * @param int $delta
   422  */
   429  */
   423 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
   430 function _wp_ajax_delete_comment_response( $comment_id, $delta = -1 ) {
   424 	$total    = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0;
   431 	$total    = isset( $_POST['_total'] ) ? (int) $_POST['_total'] : 0;
   425 	$per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
   432 	$per_page = isset( $_POST['_per_page'] ) ? (int) $_POST['_per_page'] : 0;
   426 	$page     = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0;
   433 	$page     = isset( $_POST['_page'] ) ? (int) $_POST['_page'] : 0;
   427 	$url      = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : '';
   434 	$url      = isset( $_POST['_url'] ) ? esc_url_raw( $_POST['_url'] ) : '';
   428 
   435 
   429 	// JS didn't send us everything we need to know. Just die with success message
   436 	// JS didn't send us everything we need to know. Just die with success message.
   430 	if ( ! $total || ! $per_page || ! $page || ! $url ) {
   437 	if ( ! $total || ! $per_page || ! $page || ! $url ) {
   431 		$time           = time();
   438 		$time           = time();
   432 		$comment        = get_comment( $comment_id );
   439 		$comment        = get_comment( $comment_id );
   433 		$comment_status = '';
   440 		$comment_status = '';
   434 		$comment_link   = '';
   441 		$comment_link   = '';
   452 					'status'               => $comment_status,
   459 					'status'               => $comment_status,
   453 					'postId'               => $comment ? $comment->comment_post_ID : '',
   460 					'postId'               => $comment ? $comment->comment_post_ID : '',
   454 					'time'                 => $time,
   461 					'time'                 => $time,
   455 					'in_moderation'        => $counts->moderated,
   462 					'in_moderation'        => $counts->moderated,
   456 					'i18n_comments_text'   => sprintf(
   463 					'i18n_comments_text'   => sprintf(
   457 						/* translators: %s: number of comments approved */
   464 						/* translators: %s: Number of comments. */
   458 						_n( '%s Comment', '%s Comments', $counts->approved ),
   465 						_n( '%s Comment', '%s Comments', $counts->approved ),
   459 						number_format_i18n( $counts->approved )
   466 						number_format_i18n( $counts->approved )
   460 					),
   467 					),
   461 					'i18n_moderation_text' => sprintf(
   468 					'i18n_moderation_text' => sprintf(
   462 						/* translators: %s: number of comments in moderation */
   469 						/* translators: %s: Number of comments. */
   463 						_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
   470 						_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
   464 						number_format_i18n( $counts->moderated )
   471 						number_format_i18n( $counts->moderated )
   465 					),
   472 					),
   466 					'comment_link'         => $comment_link,
   473 					'comment_link'         => $comment_link,
   467 				),
   474 				),
   473 	$total += $delta;
   480 	$total += $delta;
   474 	if ( $total < 0 ) {
   481 	if ( $total < 0 ) {
   475 		$total = 0;
   482 		$total = 0;
   476 	}
   483 	}
   477 
   484 
   478 	// Only do the expensive stuff on a page-break, and about 1 other time per page
   485 	// Only do the expensive stuff on a page-break, and about 1 other time per page.
   479 	if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
   486 	if ( 0 == $total % $per_page || 1 == mt_rand( 1, $per_page ) ) {
   480 		$post_id = 0;
   487 		$post_id = 0;
   481 		// What type of comment count are we looking for?
   488 		// What type of comment count are we looking for?
   482 		$status = 'all';
   489 		$status = 'all';
   483 		$parsed = parse_url( $url );
   490 		$parsed = parse_url( $url );
       
   491 
   484 		if ( isset( $parsed['query'] ) ) {
   492 		if ( isset( $parsed['query'] ) ) {
   485 			parse_str( $parsed['query'], $query_vars );
   493 			parse_str( $parsed['query'], $query_vars );
       
   494 
   486 			if ( ! empty( $query_vars['comment_status'] ) ) {
   495 			if ( ! empty( $query_vars['comment_status'] ) ) {
   487 				$status = $query_vars['comment_status'];
   496 				$status = $query_vars['comment_status'];
   488 			}
   497 			}
       
   498 
   489 			if ( ! empty( $query_vars['p'] ) ) {
   499 			if ( ! empty( $query_vars['p'] ) ) {
   490 				$post_id = (int) $query_vars['p'];
   500 				$post_id = (int) $query_vars['p'];
   491 			}
   501 			}
       
   502 
   492 			if ( ! empty( $query_vars['comment_type'] ) ) {
   503 			if ( ! empty( $query_vars['comment_type'] ) ) {
   493 				$type = $query_vars['comment_type'];
   504 				$type = $query_vars['comment_type'];
   494 			}
   505 			}
   495 		}
   506 		}
   496 
   507 
   516 			'what'         => 'comment',
   527 			'what'         => 'comment',
   517 			'id'           => $comment_id,
   528 			'id'           => $comment_id,
   518 			'supplemental' => array(
   529 			'supplemental' => array(
   519 				'status'               => $comment ? $comment->comment_approved : '',
   530 				'status'               => $comment ? $comment->comment_approved : '',
   520 				'postId'               => $comment ? $comment->comment_post_ID : '',
   531 				'postId'               => $comment ? $comment->comment_post_ID : '',
   521 				/* translators: %s: number of comments */
   532 				/* translators: %s: Number of comments. */
   522 				'total_items_i18n'     => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ),
   533 				'total_items_i18n'     => sprintf( _n( '%s item', '%s items', $total ), number_format_i18n( $total ) ),
   523 				'total_pages'          => ceil( $total / $per_page ),
   534 				'total_pages'          => ceil( $total / $per_page ),
   524 				'total_pages_i18n'     => number_format_i18n( ceil( $total / $per_page ) ),
   535 				'total_pages_i18n'     => number_format_i18n( ceil( $total / $per_page ) ),
   525 				'total'                => $total,
   536 				'total'                => $total,
   526 				'time'                 => $time,
   537 				'time'                 => $time,
   527 				'in_moderation'        => $counts->moderated,
   538 				'in_moderation'        => $counts->moderated,
   528 				'i18n_moderation_text' => sprintf(
   539 				'i18n_moderation_text' => sprintf(
   529 					/* translators: %s: number of comments in moderation */
   540 					/* translators: %s: Number of comments. */
   530 					_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
   541 					_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
   531 					number_format_i18n( $counts->moderated )
   542 					number_format_i18n( $counts->moderated )
   532 				),
   543 				),
   533 			),
   544 			),
   534 		)
   545 		)
   541 //
   552 //
   542 
   553 
   543 /**
   554 /**
   544  * Ajax handler for adding a hierarchical term.
   555  * Ajax handler for adding a hierarchical term.
   545  *
   556  *
       
   557  * @since 3.1.0
   546  * @access private
   558  * @access private
   547  * @since 3.1.0
       
   548  */
   559  */
   549 function _wp_ajax_add_hierarchical_term() {
   560 function _wp_ajax_add_hierarchical_term() {
   550 	$action   = $_POST['action'];
   561 	$action   = $_POST['action'];
   551 	$taxonomy = get_taxonomy( substr( $action, 4 ) );
   562 	$taxonomy = get_taxonomy( substr( $action, 4 ) );
   552 	check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
   563 	check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );
       
   564 
   553 	if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
   565 	if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
   554 		wp_die( -1 );
   566 		wp_die( -1 );
   555 	}
   567 	}
       
   568 
   556 	$names  = explode( ',', $_POST[ 'new' . $taxonomy->name ] );
   569 	$names  = explode( ',', $_POST[ 'new' . $taxonomy->name ] );
   557 	$parent = isset( $_POST[ 'new' . $taxonomy->name . '_parent' ] ) ? (int) $_POST[ 'new' . $taxonomy->name . '_parent' ] : 0;
   570 	$parent = isset( $_POST[ 'new' . $taxonomy->name . '_parent' ] ) ? (int) $_POST[ 'new' . $taxonomy->name . '_parent' ] : 0;
       
   571 
   558 	if ( 0 > $parent ) {
   572 	if ( 0 > $parent ) {
   559 		$parent = 0;
   573 		$parent = 0;
   560 	}
   574 	}
   561 	if ( $taxonomy->name == 'category' ) {
   575 
       
   576 	if ( 'category' === $taxonomy->name ) {
   562 		$post_category = isset( $_POST['post_category'] ) ? (array) $_POST['post_category'] : array();
   577 		$post_category = isset( $_POST['post_category'] ) ? (array) $_POST['post_category'] : array();
   563 	} else {
   578 	} else {
   564 		$post_category = ( isset( $_POST['tax_input'] ) && isset( $_POST['tax_input'][ $taxonomy->name ] ) ) ? (array) $_POST['tax_input'][ $taxonomy->name ] : array();
   579 		$post_category = ( isset( $_POST['tax_input'] ) && isset( $_POST['tax_input'][ $taxonomy->name ] ) ) ? (array) $_POST['tax_input'][ $taxonomy->name ] : array();
   565 	}
   580 	}
       
   581 
   566 	$checked_categories = array_map( 'absint', (array) $post_category );
   582 	$checked_categories = array_map( 'absint', (array) $post_category );
   567 	$popular_ids        = wp_popular_terms_checklist( $taxonomy->name, 0, 10, false );
   583 	$popular_ids        = wp_popular_terms_checklist( $taxonomy->name, 0, 10, false );
   568 
   584 
   569 	foreach ( $names as $cat_name ) {
   585 	foreach ( $names as $cat_name ) {
   570 		$cat_name          = trim( $cat_name );
   586 		$cat_name          = trim( $cat_name );
   571 		$category_nicename = sanitize_title( $cat_name );
   587 		$category_nicename = sanitize_title( $cat_name );
       
   588 
   572 		if ( '' === $category_nicename ) {
   589 		if ( '' === $category_nicename ) {
   573 			continue;
   590 			continue;
   574 		}
   591 		}
   575 
   592 
   576 		$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
   593 		$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );
       
   594 
   577 		if ( ! $cat_id || is_wp_error( $cat_id ) ) {
   595 		if ( ! $cat_id || is_wp_error( $cat_id ) ) {
   578 			continue;
   596 			continue;
   579 		} else {
   597 		} else {
   580 			$cat_id = $cat_id['term_id'];
   598 			$cat_id = $cat_id['term_id'];
   581 		}
   599 		}
       
   600 
   582 		$checked_categories[] = $cat_id;
   601 		$checked_categories[] = $cat_id;
   583 		if ( $parent ) { // Do these all at once in a second
   602 
       
   603 		if ( $parent ) { // Do these all at once in a second.
   584 			continue;
   604 			continue;
   585 		}
   605 		}
   586 
   606 
   587 		ob_start();
   607 		ob_start();
   588 
   608 
   604 			'data'     => str_replace( array( "\n", "\t" ), '', $data ),
   624 			'data'     => str_replace( array( "\n", "\t" ), '', $data ),
   605 			'position' => -1,
   625 			'position' => -1,
   606 		);
   626 		);
   607 	}
   627 	}
   608 
   628 
   609 	if ( $parent ) { // Foncy - replace the parent and all its children
   629 	if ( $parent ) { // Foncy - replace the parent and all its children.
   610 		$parent  = get_term( $parent, $taxonomy->name );
   630 		$parent  = get_term( $parent, $taxonomy->name );
   611 		$term_id = $parent->term_id;
   631 		$term_id = $parent->term_id;
   612 
   632 
   613 		while ( $parent->parent ) { // get the top parent
   633 		while ( $parent->parent ) { // Get the top parent.
   614 			$parent = get_term( $parent->parent, $taxonomy->name );
   634 			$parent = get_term( $parent->parent, $taxonomy->name );
   615 			if ( is_wp_error( $parent ) ) {
   635 			if ( is_wp_error( $parent ) ) {
   616 				break;
   636 				break;
   617 			}
   637 			}
   618 			$term_id = $parent->term_id;
   638 			$term_id = $parent->term_id;
   667  * @since 3.1.0
   687  * @since 3.1.0
   668  */
   688  */
   669 function wp_ajax_delete_comment() {
   689 function wp_ajax_delete_comment() {
   670 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   690 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   671 
   691 
   672 	if ( ! $comment = get_comment( $id ) ) {
   692 	$comment = get_comment( $id );
       
   693 
       
   694 	if ( ! $comment ) {
   673 		wp_die( time() );
   695 		wp_die( time() );
   674 	}
   696 	}
       
   697 
   675 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
   698 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) {
   676 		wp_die( -1 );
   699 		wp_die( -1 );
   677 	}
   700 	}
   678 
   701 
   679 	check_ajax_referer( "delete-comment_$id" );
   702 	check_ajax_referer( "delete-comment_$id" );
   680 	$status = wp_get_comment_status( $comment );
   703 	$status = wp_get_comment_status( $comment );
   681 
   704 	$delta  = -1;
   682 	$delta = -1;
   705 
   683 	if ( isset( $_POST['trash'] ) && 1 == $_POST['trash'] ) {
   706 	if ( isset( $_POST['trash'] ) && 1 == $_POST['trash'] ) {
   684 		if ( 'trash' == $status ) {
   707 		if ( 'trash' === $status ) {
   685 			wp_die( time() );
   708 			wp_die( time() );
   686 		}
   709 		}
       
   710 
   687 		$r = wp_trash_comment( $comment );
   711 		$r = wp_trash_comment( $comment );
   688 	} elseif ( isset( $_POST['untrash'] ) && 1 == $_POST['untrash'] ) {
   712 	} elseif ( isset( $_POST['untrash'] ) && 1 == $_POST['untrash'] ) {
   689 		if ( 'trash' != $status ) {
   713 		if ( 'trash' !== $status ) {
   690 			wp_die( time() );
   714 			wp_die( time() );
   691 		}
   715 		}
       
   716 
   692 		$r = wp_untrash_comment( $comment );
   717 		$r = wp_untrash_comment( $comment );
   693 		if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'trash' ) { // undo trash, not in trash
   718 
       
   719 		// Undo trash, not in Trash.
       
   720 		if ( ! isset( $_POST['comment_status'] ) || 'trash' !== $_POST['comment_status'] ) {
   694 			$delta = 1;
   721 			$delta = 1;
   695 		}
   722 		}
   696 	} elseif ( isset( $_POST['spam'] ) && 1 == $_POST['spam'] ) {
   723 	} elseif ( isset( $_POST['spam'] ) && 1 == $_POST['spam'] ) {
   697 		if ( 'spam' == $status ) {
   724 		if ( 'spam' === $status ) {
   698 			wp_die( time() );
   725 			wp_die( time() );
   699 		}
   726 		}
       
   727 
   700 		$r = wp_spam_comment( $comment );
   728 		$r = wp_spam_comment( $comment );
   701 	} elseif ( isset( $_POST['unspam'] ) && 1 == $_POST['unspam'] ) {
   729 	} elseif ( isset( $_POST['unspam'] ) && 1 == $_POST['unspam'] ) {
   702 		if ( 'spam' != $status ) {
   730 		if ( 'spam' !== $status ) {
   703 			wp_die( time() );
   731 			wp_die( time() );
   704 		}
   732 		}
       
   733 
   705 		$r = wp_unspam_comment( $comment );
   734 		$r = wp_unspam_comment( $comment );
   706 		if ( ! isset( $_POST['comment_status'] ) || $_POST['comment_status'] != 'spam' ) { // undo spam, not in spam
   735 
       
   736 		// Undo spam, not in spam.
       
   737 		if ( ! isset( $_POST['comment_status'] ) || 'spam' !== $_POST['comment_status'] ) {
   707 			$delta = 1;
   738 			$delta = 1;
   708 		}
   739 		}
   709 	} elseif ( isset( $_POST['delete'] ) && 1 == $_POST['delete'] ) {
   740 	} elseif ( isset( $_POST['delete'] ) && 1 == $_POST['delete'] ) {
   710 		$r = wp_delete_comment( $comment );
   741 		$r = wp_delete_comment( $comment );
   711 	} else {
   742 	} else {
   712 		wp_die( -1 );
   743 		wp_die( -1 );
   713 	}
   744 	}
   714 
   745 
   715 	if ( $r ) { // Decide if we need to send back '1' or a more complicated response including page links and comment counts
   746 	if ( $r ) {
       
   747 		// Decide if we need to send back '1' or a more complicated response including page links and comment counts.
   716 		_wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
   748 		_wp_ajax_delete_comment_response( $comment->comment_ID, $delta );
   717 	}
   749 	}
       
   750 
   718 	wp_die( 0 );
   751 	wp_die( 0 );
   719 }
   752 }
   720 
   753 
   721 /**
   754 /**
   722  * Ajax handler for deleting a tag.
   755  * Ajax handler for deleting a tag.
   731 		wp_die( -1 );
   764 		wp_die( -1 );
   732 	}
   765 	}
   733 
   766 
   734 	$taxonomy = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
   767 	$taxonomy = ! empty( $_POST['taxonomy'] ) ? $_POST['taxonomy'] : 'post_tag';
   735 	$tag      = get_term( $tag_id, $taxonomy );
   768 	$tag      = get_term( $tag_id, $taxonomy );
       
   769 
   736 	if ( ! $tag || is_wp_error( $tag ) ) {
   770 	if ( ! $tag || is_wp_error( $tag ) ) {
   737 		wp_die( 1 );
   771 		wp_die( 1 );
   738 	}
   772 	}
   739 
   773 
   740 	if ( wp_delete_term( $tag_id, $taxonomy ) ) {
   774 	if ( wp_delete_term( $tag_id, $taxonomy ) ) {
   751  */
   785  */
   752 function wp_ajax_delete_link() {
   786 function wp_ajax_delete_link() {
   753 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   787 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   754 
   788 
   755 	check_ajax_referer( "delete-bookmark_$id" );
   789 	check_ajax_referer( "delete-bookmark_$id" );
       
   790 
   756 	if ( ! current_user_can( 'manage_links' ) ) {
   791 	if ( ! current_user_can( 'manage_links' ) ) {
   757 		wp_die( -1 );
   792 		wp_die( -1 );
   758 	}
   793 	}
   759 
   794 
   760 	$link = get_bookmark( $id );
   795 	$link = get_bookmark( $id );
   776  */
   811  */
   777 function wp_ajax_delete_meta() {
   812 function wp_ajax_delete_meta() {
   778 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   813 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   779 
   814 
   780 	check_ajax_referer( "delete-meta_$id" );
   815 	check_ajax_referer( "delete-meta_$id" );
   781 	if ( ! $meta = get_metadata_by_mid( 'post', $id ) ) {
   816 	$meta = get_metadata_by_mid( 'post', $id );
       
   817 
       
   818 	if ( ! $meta ) {
   782 		wp_die( 1 );
   819 		wp_die( 1 );
   783 	}
   820 	}
   784 
   821 
   785 	if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $meta->post_id, $meta->meta_key ) ) {
   822 	if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $meta->post_id, $meta->meta_key ) ) {
   786 		wp_die( -1 );
   823 		wp_die( -1 );
   787 	}
   824 	}
       
   825 
   788 	if ( delete_meta( $meta->meta_id ) ) {
   826 	if ( delete_meta( $meta->meta_id ) ) {
   789 		wp_die( 1 );
   827 		wp_die( 1 );
   790 	}
   828 	}
       
   829 
   791 	wp_die( 0 );
   830 	wp_die( 0 );
   792 }
   831 }
   793 
   832 
   794 /**
   833 /**
   795  * Ajax handler for deleting a post.
   834  * Ajax handler for deleting a post.
   800  */
   839  */
   801 function wp_ajax_delete_post( $action ) {
   840 function wp_ajax_delete_post( $action ) {
   802 	if ( empty( $action ) ) {
   841 	if ( empty( $action ) ) {
   803 		$action = 'delete-post';
   842 		$action = 'delete-post';
   804 	}
   843 	}
       
   844 
   805 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   845 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   806 
       
   807 	check_ajax_referer( "{$action}_$id" );
   846 	check_ajax_referer( "{$action}_$id" );
       
   847 
   808 	if ( ! current_user_can( 'delete_post', $id ) ) {
   848 	if ( ! current_user_can( 'delete_post', $id ) ) {
   809 		wp_die( -1 );
   849 		wp_die( -1 );
   810 	}
   850 	}
   811 
   851 
   812 	if ( ! get_post( $id ) ) {
   852 	if ( ! get_post( $id ) ) {
   819 		wp_die( 0 );
   859 		wp_die( 0 );
   820 	}
   860 	}
   821 }
   861 }
   822 
   862 
   823 /**
   863 /**
   824  * Ajax handler for sending a post to the trash.
   864  * Ajax handler for sending a post to the Trash.
   825  *
   865  *
   826  * @since 3.1.0
   866  * @since 3.1.0
   827  *
   867  *
   828  * @param string $action Action to perform.
   868  * @param string $action Action to perform.
   829  */
   869  */
   830 function wp_ajax_trash_post( $action ) {
   870 function wp_ajax_trash_post( $action ) {
   831 	if ( empty( $action ) ) {
   871 	if ( empty( $action ) ) {
   832 		$action = 'trash-post';
   872 		$action = 'trash-post';
   833 	}
   873 	}
       
   874 
   834 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   875 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   835 
       
   836 	check_ajax_referer( "{$action}_$id" );
   876 	check_ajax_referer( "{$action}_$id" );
       
   877 
   837 	if ( ! current_user_can( 'delete_post', $id ) ) {
   878 	if ( ! current_user_can( 'delete_post', $id ) ) {
   838 		wp_die( -1 );
   879 		wp_die( -1 );
   839 	}
   880 	}
   840 
   881 
   841 	if ( ! get_post( $id ) ) {
   882 	if ( ! get_post( $id ) ) {
   842 		wp_die( 1 );
   883 		wp_die( 1 );
   843 	}
   884 	}
   844 
   885 
   845 	if ( 'trash-post' == $action ) {
   886 	if ( 'trash-post' === $action ) {
   846 		$done = wp_trash_post( $id );
   887 		$done = wp_trash_post( $id );
   847 	} else {
   888 	} else {
   848 		$done = wp_untrash_post( $id );
   889 		$done = wp_untrash_post( $id );
   849 	}
   890 	}
   850 
   891 
   854 
   895 
   855 	wp_die( 0 );
   896 	wp_die( 0 );
   856 }
   897 }
   857 
   898 
   858 /**
   899 /**
   859  * Ajax handler to restore a post from the trash.
   900  * Ajax handler to restore a post from the Trash.
   860  *
   901  *
   861  * @since 3.1.0
   902  * @since 3.1.0
   862  *
   903  *
   863  * @param string $action Action to perform.
   904  * @param string $action Action to perform.
   864  */
   905  */
   865 function wp_ajax_untrash_post( $action ) {
   906 function wp_ajax_untrash_post( $action ) {
   866 	if ( empty( $action ) ) {
   907 	if ( empty( $action ) ) {
   867 		$action = 'untrash-post';
   908 		$action = 'untrash-post';
   868 	}
   909 	}
       
   910 
   869 	wp_ajax_trash_post( $action );
   911 	wp_ajax_trash_post( $action );
   870 }
   912 }
   871 
   913 
   872 /**
   914 /**
   873  * Ajax handler to delete a page.
   915  * Ajax handler to delete a page.
   878  */
   920  */
   879 function wp_ajax_delete_page( $action ) {
   921 function wp_ajax_delete_page( $action ) {
   880 	if ( empty( $action ) ) {
   922 	if ( empty( $action ) ) {
   881 		$action = 'delete-page';
   923 		$action = 'delete-page';
   882 	}
   924 	}
       
   925 
   883 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   926 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   884 
       
   885 	check_ajax_referer( "{$action}_$id" );
   927 	check_ajax_referer( "{$action}_$id" );
       
   928 
   886 	if ( ! current_user_can( 'delete_page', $id ) ) {
   929 	if ( ! current_user_can( 'delete_page', $id ) ) {
   887 		wp_die( -1 );
   930 		wp_die( -1 );
   888 	}
   931 	}
   889 
   932 
   890 	if ( ! get_post( $id ) ) {
   933 	if ( ! get_post( $id ) ) {
   902  * Ajax handler to dim a comment.
   945  * Ajax handler to dim a comment.
   903  *
   946  *
   904  * @since 3.1.0
   947  * @since 3.1.0
   905  */
   948  */
   906 function wp_ajax_dim_comment() {
   949 function wp_ajax_dim_comment() {
   907 	$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   950 	$id      = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;
   908 
   951 	$comment = get_comment( $id );
   909 	if ( ! $comment = get_comment( $id ) ) {
   952 
       
   953 	if ( ! $comment ) {
   910 		$x = new WP_Ajax_Response(
   954 		$x = new WP_Ajax_Response(
   911 			array(
   955 			array(
   912 				'what' => 'comment',
   956 				'what' => 'comment',
   913 				/* translators: %d: comment ID */
   957 				'id'   => new WP_Error(
   914 				'id'   => new WP_Error( 'invalid_comment', sprintf( __( 'Comment %d does not exist' ), $id ) ),
   958 					'invalid_comment',
       
   959 					/* translators: %d: Comment ID. */
       
   960 					sprintf( __( 'Comment %d does not exist' ), $id )
       
   961 				),
   915 			)
   962 			)
   916 		);
   963 		);
   917 		$x->send();
   964 		$x->send();
   918 	}
   965 	}
   919 
   966 
   920 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) ) {
   967 	if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && ! current_user_can( 'moderate_comments' ) ) {
   921 		wp_die( -1 );
   968 		wp_die( -1 );
   922 	}
   969 	}
   923 
   970 
   924 	$current = wp_get_comment_status( $comment );
   971 	$current = wp_get_comment_status( $comment );
       
   972 
   925 	if ( isset( $_POST['new'] ) && $_POST['new'] == $current ) {
   973 	if ( isset( $_POST['new'] ) && $_POST['new'] == $current ) {
   926 		wp_die( time() );
   974 		wp_die( time() );
   927 	}
   975 	}
   928 
   976 
   929 	check_ajax_referer( "approve-comment_$id" );
   977 	check_ajax_referer( "approve-comment_$id" );
   930 	if ( in_array( $current, array( 'unapproved', 'spam' ) ) ) {
   978 
       
   979 	if ( in_array( $current, array( 'unapproved', 'spam' ), true ) ) {
   931 		$result = wp_set_comment_status( $comment, 'approve', true );
   980 		$result = wp_set_comment_status( $comment, 'approve', true );
   932 	} else {
   981 	} else {
   933 		$result = wp_set_comment_status( $comment, 'hold', true );
   982 		$result = wp_set_comment_status( $comment, 'hold', true );
   934 	}
   983 	}
   935 
   984 
   941 			)
   990 			)
   942 		);
   991 		);
   943 		$x->send();
   992 		$x->send();
   944 	}
   993 	}
   945 
   994 
   946 	// Decide if we need to send back '1' or a more complicated response including page links and comment counts
   995 	// Decide if we need to send back '1' or a more complicated response including page links and comment counts.
   947 	_wp_ajax_delete_comment_response( $comment->comment_ID );
   996 	_wp_ajax_delete_comment_response( $comment->comment_ID );
   948 	wp_die( 0 );
   997 	wp_die( 0 );
   949 }
   998 }
   950 
   999 
   951 /**
  1000 /**
   957  */
  1006  */
   958 function wp_ajax_add_link_category( $action ) {
  1007 function wp_ajax_add_link_category( $action ) {
   959 	if ( empty( $action ) ) {
  1008 	if ( empty( $action ) ) {
   960 		$action = 'add-link-category';
  1009 		$action = 'add-link-category';
   961 	}
  1010 	}
       
  1011 
   962 	check_ajax_referer( $action );
  1012 	check_ajax_referer( $action );
   963 	$tax = get_taxonomy( 'link_category' );
  1013 	$tax = get_taxonomy( 'link_category' );
       
  1014 
   964 	if ( ! current_user_can( $tax->cap->manage_terms ) ) {
  1015 	if ( ! current_user_can( $tax->cap->manage_terms ) ) {
   965 		wp_die( -1 );
  1016 		wp_die( -1 );
   966 	}
  1017 	}
       
  1018 
   967 	$names = explode( ',', wp_unslash( $_POST['newcat'] ) );
  1019 	$names = explode( ',', wp_unslash( $_POST['newcat'] ) );
   968 	$x     = new WP_Ajax_Response();
  1020 	$x     = new WP_Ajax_Response();
       
  1021 
   969 	foreach ( $names as $cat_name ) {
  1022 	foreach ( $names as $cat_name ) {
   970 		$cat_name = trim( $cat_name );
  1023 		$cat_name = trim( $cat_name );
   971 		$slug     = sanitize_title( $cat_name );
  1024 		$slug     = sanitize_title( $cat_name );
       
  1025 
   972 		if ( '' === $slug ) {
  1026 		if ( '' === $slug ) {
   973 			continue;
  1027 			continue;
   974 		}
  1028 		}
   975 
  1029 
   976 		$cat_id = wp_insert_term( $cat_name, 'link_category' );
  1030 		$cat_id = wp_insert_term( $cat_name, 'link_category' );
       
  1031 
   977 		if ( ! $cat_id || is_wp_error( $cat_id ) ) {
  1032 		if ( ! $cat_id || is_wp_error( $cat_id ) ) {
   978 			continue;
  1033 			continue;
   979 		} else {
  1034 		} else {
   980 			$cat_id = $cat_id['term_id'];
  1035 			$cat_id = $cat_id['term_id'];
   981 		}
  1036 		}
       
  1037 
   982 		$cat_name = esc_html( $cat_name );
  1038 		$cat_name = esc_html( $cat_name );
       
  1039 
   983 		$x->add(
  1040 		$x->add(
   984 			array(
  1041 			array(
   985 				'what'     => 'link-category',
  1042 				'what'     => 'link-category',
   986 				'id'       => $cat_id,
  1043 				'id'       => $cat_id,
   987 				'data'     => "<li id='link-category-$cat_id'><label for='in-link-category-$cat_id' class='selectit'><input value='" . esc_attr( $cat_id ) . "' type='checkbox' checked='checked' name='link_category[]' id='in-link-category-$cat_id'/> $cat_name</label></li>",
  1044 				'data'     => "<li id='link-category-$cat_id'><label for='in-link-category-$cat_id' class='selectit'><input value='" . esc_attr( $cat_id ) . "' type='checkbox' checked='checked' name='link_category[]' id='in-link-category-$cat_id'/> $cat_name</label></li>",
  1008 
  1065 
  1009 	$x = new WP_Ajax_Response();
  1066 	$x = new WP_Ajax_Response();
  1010 
  1067 
  1011 	$tag = wp_insert_term( $_POST['tag-name'], $taxonomy, $_POST );
  1068 	$tag = wp_insert_term( $_POST['tag-name'], $taxonomy, $_POST );
  1012 
  1069 
  1013 	if ( ! $tag || is_wp_error( $tag ) || ( ! $tag = get_term( $tag['term_id'], $taxonomy ) ) ) {
  1070 	if ( $tag && ! is_wp_error( $tag ) ) {
       
  1071 		$tag = get_term( $tag['term_id'], $taxonomy );
       
  1072 	}
       
  1073 
       
  1074 	if ( ! $tag || is_wp_error( $tag ) ) {
  1014 		$message = __( 'An error has occurred. Please reload the page and try again.' );
  1075 		$message = __( 'An error has occurred. Please reload the page and try again.' );
       
  1076 
  1015 		if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1077 		if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  1016 			$message = $tag->get_error_message();
  1078 			$message = $tag->get_error_message();
  1017 		}
  1079 		}
  1018 
  1080 
  1019 		$x->add(
  1081 		$x->add(
  1045 		array(
  1107 		array(
  1046 			'what'         => 'taxonomy',
  1108 			'what'         => 'taxonomy',
  1047 			'supplemental' => compact( 'parents', 'noparents' ),
  1109 			'supplemental' => compact( 'parents', 'noparents' ),
  1048 		)
  1110 		)
  1049 	);
  1111 	);
       
  1112 
  1050 	$x->add(
  1113 	$x->add(
  1051 		array(
  1114 		array(
  1052 			'what'         => 'term',
  1115 			'what'         => 'term',
  1053 			'position'     => $level,
  1116 			'position'     => $level,
  1054 			'supplemental' => (array) $tag,
  1117 			'supplemental' => (array) $tag,
  1055 		)
  1118 		)
  1056 	);
  1119 	);
       
  1120 
  1057 	$x->send();
  1121 	$x->send();
  1058 }
  1122 }
  1059 
  1123 
  1060 /**
  1124 /**
  1061  * Ajax handler for getting a tagcloud.
  1125  * Ajax handler for getting a tagcloud.
  1067 		wp_die( 0 );
  1131 		wp_die( 0 );
  1068 	}
  1132 	}
  1069 
  1133 
  1070 	$taxonomy = sanitize_key( $_POST['tax'] );
  1134 	$taxonomy = sanitize_key( $_POST['tax'] );
  1071 	$tax      = get_taxonomy( $taxonomy );
  1135 	$tax      = get_taxonomy( $taxonomy );
       
  1136 
  1072 	if ( ! $tax ) {
  1137 	if ( ! $tax ) {
  1073 		wp_die( 0 );
  1138 		wp_die( 0 );
  1074 	}
  1139 	}
  1075 
  1140 
  1076 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
  1141 	if ( ! current_user_can( $tax->cap->assign_terms ) ) {
  1077 		wp_die( -1 );
  1142 		wp_die( -1 );
  1078 	}
  1143 	}
  1079 
  1144 
  1080 	$tags = get_terms(
  1145 	$tags = get_terms(
  1081 		$taxonomy,
       
  1082 		array(
  1146 		array(
  1083 			'number'  => 45,
  1147 			'taxonomy' => $taxonomy,
  1084 			'orderby' => 'count',
  1148 			'number'   => 45,
  1085 			'order'   => 'DESC',
  1149 			'orderby'  => 'count',
       
  1150 			'order'    => 'DESC',
  1086 		)
  1151 		)
  1087 	);
  1152 	);
  1088 
  1153 
  1089 	if ( empty( $tags ) ) {
  1154 	if ( empty( $tags ) ) {
  1090 		wp_die( $tax->labels->not_found );
  1155 		wp_die( $tax->labels->not_found );
  1097 	foreach ( $tags as $key => $tag ) {
  1162 	foreach ( $tags as $key => $tag ) {
  1098 		$tags[ $key ]->link = '#';
  1163 		$tags[ $key ]->link = '#';
  1099 		$tags[ $key ]->id   = $tag->term_id;
  1164 		$tags[ $key ]->id   = $tag->term_id;
  1100 	}
  1165 	}
  1101 
  1166 
  1102 	// We need raw tag names here, so don't filter the output
  1167 	// We need raw tag names here, so don't filter the output.
  1103 	$return = wp_generate_tag_cloud(
  1168 	$return = wp_generate_tag_cloud(
  1104 		$tags,
  1169 		$tags,
  1105 		array(
  1170 		array(
  1106 			'filter' => 0,
  1171 			'filter' => 0,
  1107 			'format' => 'list',
  1172 			'format' => 'list',
  1111 	if ( empty( $return ) ) {
  1176 	if ( empty( $return ) ) {
  1112 		wp_die( 0 );
  1177 		wp_die( 0 );
  1113 	}
  1178 	}
  1114 
  1179 
  1115 	echo $return;
  1180 	echo $return;
  1116 
       
  1117 	wp_die();
  1181 	wp_die();
  1118 }
  1182 }
  1119 
  1183 
  1120 /**
  1184 /**
  1121  * Ajax handler for getting comments.
  1185  * Ajax handler for getting comments.
  1122  *
  1186  *
  1123  * @since 3.1.0
  1187  * @since 3.1.0
  1124  *
  1188  *
  1125  * @global int           $post_id
  1189  * @global int $post_id
  1126  *
  1190  *
  1127  * @param string $action Action to perform.
  1191  * @param string $action Action to perform.
  1128  */
  1192  */
  1129 function wp_ajax_get_comments( $action ) {
  1193 function wp_ajax_get_comments( $action ) {
  1130 	global $post_id;
  1194 	global $post_id;
       
  1195 
  1131 	if ( empty( $action ) ) {
  1196 	if ( empty( $action ) ) {
  1132 		$action = 'get-comments';
  1197 		$action = 'get-comments';
  1133 	}
  1198 	}
       
  1199 
  1134 	check_ajax_referer( $action );
  1200 	check_ajax_referer( $action );
  1135 
  1201 
  1136 	if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) {
  1202 	if ( empty( $post_id ) && ! empty( $_REQUEST['p'] ) ) {
  1137 		$id = absint( $_REQUEST['p'] );
  1203 		$id = absint( $_REQUEST['p'] );
  1138 		if ( ! empty( $id ) ) {
  1204 		if ( ! empty( $id ) ) {
  1155 	if ( ! $wp_list_table->has_items() ) {
  1221 	if ( ! $wp_list_table->has_items() ) {
  1156 		wp_die( 1 );
  1222 		wp_die( 1 );
  1157 	}
  1223 	}
  1158 
  1224 
  1159 	$x = new WP_Ajax_Response();
  1225 	$x = new WP_Ajax_Response();
       
  1226 
  1160 	ob_start();
  1227 	ob_start();
  1161 	foreach ( $wp_list_table->items as $comment ) {
  1228 	foreach ( $wp_list_table->items as $comment ) {
  1162 		if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && 0 === $comment->comment_approved ) {
  1229 		if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) && 0 === $comment->comment_approved ) {
  1163 			continue;
  1230 			continue;
  1164 		}
  1231 		}
  1171 		array(
  1238 		array(
  1172 			'what' => 'comments',
  1239 			'what' => 'comments',
  1173 			'data' => $comment_list_item,
  1240 			'data' => $comment_list_item,
  1174 		)
  1241 		)
  1175 	);
  1242 	);
       
  1243 
  1176 	$x->send();
  1244 	$x->send();
  1177 }
  1245 }
  1178 
  1246 
  1179 /**
  1247 /**
  1180  * Ajax handler for replying to a comment.
  1248  * Ajax handler for replying to a comment.
  1190 
  1258 
  1191 	check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
  1259 	check_ajax_referer( $action, '_ajax_nonce-replyto-comment' );
  1192 
  1260 
  1193 	$comment_post_ID = (int) $_POST['comment_post_ID'];
  1261 	$comment_post_ID = (int) $_POST['comment_post_ID'];
  1194 	$post            = get_post( $comment_post_ID );
  1262 	$post            = get_post( $comment_post_ID );
       
  1263 
  1195 	if ( ! $post ) {
  1264 	if ( ! $post ) {
  1196 		wp_die( -1 );
  1265 		wp_die( -1 );
  1197 	}
  1266 	}
  1198 
  1267 
  1199 	if ( ! current_user_can( 'edit_post', $comment_post_ID ) ) {
  1268 	if ( ! current_user_can( 'edit_post', $comment_post_ID ) ) {
  1200 		wp_die( -1 );
  1269 		wp_die( -1 );
  1201 	}
  1270 	}
  1202 
  1271 
  1203 	if ( empty( $post->post_status ) ) {
  1272 	if ( empty( $post->post_status ) ) {
  1204 		wp_die( 1 );
  1273 		wp_die( 1 );
  1205 	} elseif ( in_array( $post->post_status, array( 'draft', 'pending', 'trash' ) ) ) {
  1274 	} elseif ( in_array( $post->post_status, array( 'draft', 'pending', 'trash' ), true ) ) {
  1206 		wp_die( __( 'ERROR: you are replying to a comment on a draft post.' ) );
  1275 		wp_die( __( 'Error: You can&#8217;t reply to a comment on a draft post.' ) );
  1207 	}
  1276 	}
  1208 
  1277 
  1209 	$user = wp_get_current_user();
  1278 	$user = wp_get_current_user();
       
  1279 
  1210 	if ( $user->exists() ) {
  1280 	if ( $user->exists() ) {
  1211 		$user_ID              = $user->ID;
  1281 		$user_ID              = $user->ID;
  1212 		$comment_author       = wp_slash( $user->display_name );
  1282 		$comment_author       = wp_slash( $user->display_name );
  1213 		$comment_author_email = wp_slash( $user->user_email );
  1283 		$comment_author_email = wp_slash( $user->user_email );
  1214 		$comment_author_url   = wp_slash( $user->user_url );
  1284 		$comment_author_url   = wp_slash( $user->user_url );
  1215 		$comment_content      = trim( $_POST['content'] );
  1285 		$comment_content      = trim( $_POST['content'] );
  1216 		$comment_type         = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : '';
  1286 		$comment_type         = isset( $_POST['comment_type'] ) ? trim( $_POST['comment_type'] ) : 'comment';
       
  1287 
  1217 		if ( current_user_can( 'unfiltered_html' ) ) {
  1288 		if ( current_user_can( 'unfiltered_html' ) ) {
  1218 			if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) ) {
  1289 			if ( ! isset( $_POST['_wp_unfiltered_html_comment'] ) ) {
  1219 				$_POST['_wp_unfiltered_html_comment'] = '';
  1290 				$_POST['_wp_unfiltered_html_comment'] = '';
  1220 			}
  1291 			}
  1221 
  1292 
  1222 			if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
  1293 			if ( wp_create_nonce( 'unfiltered-html-comment' ) != $_POST['_wp_unfiltered_html_comment'] ) {
  1223 				kses_remove_filters(); // start with a clean slate
  1294 				kses_remove_filters(); // Start with a clean slate.
  1224 				kses_init_filters(); // set up the filters
  1295 				kses_init_filters();   // Set up the filters.
  1225 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  1296 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  1226 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  1297 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  1227 			}
  1298 			}
  1228 		}
  1299 		}
  1229 	} else {
  1300 	} else {
  1230 		wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
  1301 		wp_die( __( 'Sorry, you must be logged in to reply to a comment.' ) );
  1231 	}
  1302 	}
  1232 
  1303 
  1233 	if ( '' == $comment_content ) {
  1304 	if ( '' === $comment_content ) {
  1234 		wp_die( __( 'ERROR: please type a comment.' ) );
  1305 		wp_die( __( 'Error: Please type your comment text.' ) );
  1235 	}
  1306 	}
  1236 
  1307 
  1237 	$comment_parent = 0;
  1308 	$comment_parent = 0;
       
  1309 
  1238 	if ( isset( $_POST['comment_ID'] ) ) {
  1310 	if ( isset( $_POST['comment_ID'] ) ) {
  1239 		$comment_parent = absint( $_POST['comment_ID'] );
  1311 		$comment_parent = absint( $_POST['comment_ID'] );
  1240 	}
  1312 	}
       
  1313 
  1241 	$comment_auto_approved = false;
  1314 	$comment_auto_approved = false;
  1242 	$commentdata           = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID' );
  1315 	$commentdata           = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID' );
  1243 
  1316 
  1244 	// Automatically approve parent comment.
  1317 	// Automatically approve parent comment.
  1245 	if ( ! empty( $_POST['approve_parent'] ) ) {
  1318 	if ( ! empty( $_POST['approve_parent'] ) ) {
  1246 		$parent = get_comment( $comment_parent );
  1319 		$parent = get_comment( $comment_parent );
  1247 
  1320 
  1248 		if ( $parent && $parent->comment_approved === '0' && $parent->comment_post_ID == $comment_post_ID ) {
  1321 		if ( $parent && '0' === $parent->comment_approved && $parent->comment_post_ID == $comment_post_ID ) {
  1249 			if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) {
  1322 			if ( ! current_user_can( 'edit_comment', $parent->comment_ID ) ) {
  1250 				wp_die( -1 );
  1323 				wp_die( -1 );
  1251 			}
  1324 			}
  1252 
  1325 
  1253 			if ( wp_set_comment_status( $parent, 'approve' ) ) {
  1326 			if ( wp_set_comment_status( $parent, 'approve' ) ) {
  1261 	if ( is_wp_error( $comment_id ) ) {
  1334 	if ( is_wp_error( $comment_id ) ) {
  1262 		wp_die( $comment_id->get_error_message() );
  1335 		wp_die( $comment_id->get_error_message() );
  1263 	}
  1336 	}
  1264 
  1337 
  1265 	$comment = get_comment( $comment_id );
  1338 	$comment = get_comment( $comment_id );
       
  1339 
  1266 	if ( ! $comment ) {
  1340 	if ( ! $comment ) {
  1267 		wp_die( 1 );
  1341 		wp_die( 1 );
  1268 	}
  1342 	}
  1269 
  1343 
  1270 	$position = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1344 	$position = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1271 
  1345 
  1272 	ob_start();
  1346 	ob_start();
  1273 	if ( isset( $_REQUEST['mode'] ) && 'dashboard' == $_REQUEST['mode'] ) {
  1347 	if ( isset( $_REQUEST['mode'] ) && 'dashboard' === $_REQUEST['mode'] ) {
  1274 		require_once( ABSPATH . 'wp-admin/includes/dashboard.php' );
  1348 		require_once ABSPATH . 'wp-admin/includes/dashboard.php';
  1275 		_wp_dashboard_recent_comments_row( $comment );
  1349 		_wp_dashboard_recent_comments_row( $comment );
  1276 	} else {
  1350 	} else {
  1277 		if ( isset( $_REQUEST['mode'] ) && 'single' == $_REQUEST['mode'] ) {
  1351 		if ( isset( $_REQUEST['mode'] ) && 'single' === $_REQUEST['mode'] ) {
  1278 			$wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1352 			$wp_list_table = _get_list_table( 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1279 		} else {
  1353 		} else {
  1280 			$wp_list_table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1354 			$wp_list_table = _get_list_table( 'WP_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1281 		}
  1355 		}
  1282 		$wp_list_table->single_row( $comment );
  1356 		$wp_list_table->single_row( $comment );
  1292 
  1366 
  1293 	$counts                   = wp_count_comments();
  1367 	$counts                   = wp_count_comments();
  1294 	$response['supplemental'] = array(
  1368 	$response['supplemental'] = array(
  1295 		'in_moderation'        => $counts->moderated,
  1369 		'in_moderation'        => $counts->moderated,
  1296 		'i18n_comments_text'   => sprintf(
  1370 		'i18n_comments_text'   => sprintf(
  1297 			/* translators: %s: number of comments approved */
  1371 			/* translators: %s: Number of comments. */
  1298 			_n( '%s Comment', '%s Comments', $counts->approved ),
  1372 			_n( '%s Comment', '%s Comments', $counts->approved ),
  1299 			number_format_i18n( $counts->approved )
  1373 			number_format_i18n( $counts->approved )
  1300 		),
  1374 		),
  1301 		'i18n_moderation_text' => sprintf(
  1375 		'i18n_moderation_text' => sprintf(
  1302 			/* translators: %s: number of comments in moderation */
  1376 			/* translators: %s: Number of comments. */
  1303 			_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
  1377 			_n( '%s Comment in moderation', '%s Comments in moderation', $counts->moderated ),
  1304 			number_format_i18n( $counts->moderated )
  1378 			number_format_i18n( $counts->moderated )
  1305 		),
  1379 		),
  1306 	);
  1380 	);
  1307 
  1381 
  1322  */
  1396  */
  1323 function wp_ajax_edit_comment() {
  1397 function wp_ajax_edit_comment() {
  1324 	check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
  1398 	check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' );
  1325 
  1399 
  1326 	$comment_id = (int) $_POST['comment_ID'];
  1400 	$comment_id = (int) $_POST['comment_ID'];
       
  1401 
  1327 	if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
  1402 	if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
  1328 		wp_die( -1 );
  1403 		wp_die( -1 );
  1329 	}
  1404 	}
  1330 
  1405 
  1331 	if ( '' == $_POST['content'] ) {
  1406 	if ( '' === $_POST['content'] ) {
  1332 		wp_die( __( 'ERROR: please type a comment.' ) );
  1407 		wp_die( __( 'Error: Please type your comment text.' ) );
  1333 	}
  1408 	}
  1334 
  1409 
  1335 	if ( isset( $_POST['status'] ) ) {
  1410 	if ( isset( $_POST['status'] ) ) {
  1336 		$_POST['comment_status'] = $_POST['status'];
  1411 		$_POST['comment_status'] = $_POST['status'];
  1337 	}
  1412 	}
  1338 	edit_comment();
  1413 
       
  1414 	$updated = edit_comment();
       
  1415 	if ( is_wp_error( $updated ) ) {
       
  1416 		wp_die( $updated->get_error_message() );
       
  1417 	}
  1339 
  1418 
  1340 	$position      = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1419 	$position      = ( isset( $_POST['position'] ) && (int) $_POST['position'] ) ? (int) $_POST['position'] : '-1';
  1341 	$checkbox      = ( isset( $_POST['checkbox'] ) && true == $_POST['checkbox'] ) ? 1 : 0;
  1420 	$checkbox      = ( isset( $_POST['checkbox'] ) && true == $_POST['checkbox'] ) ? 1 : 0;
  1342 	$wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1421 	$wp_list_table = _get_list_table( $checkbox ? 'WP_Comments_List_Table' : 'WP_Post_Comments_List_Table', array( 'screen' => 'edit-comments' ) );
  1343 
  1422 
  1344 	$comment = get_comment( $comment_id );
  1423 	$comment = get_comment( $comment_id );
       
  1424 
  1345 	if ( empty( $comment->comment_ID ) ) {
  1425 	if ( empty( $comment->comment_ID ) ) {
  1346 		wp_die( -1 );
  1426 		wp_die( -1 );
  1347 	}
  1427 	}
  1348 
  1428 
  1349 	ob_start();
  1429 	ob_start();
  1378 
  1458 
  1379 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1459 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1380 
  1460 
  1381 	// For performance reasons, we omit some object properties from the checklist.
  1461 	// For performance reasons, we omit some object properties from the checklist.
  1382 	// The following is a hacky way to restore them when adding non-custom items.
  1462 	// The following is a hacky way to restore them when adding non-custom items.
  1383 
       
  1384 	$menu_items_data = array();
  1463 	$menu_items_data = array();
       
  1464 
  1385 	foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
  1465 	foreach ( (array) $_POST['menu-item'] as $menu_item_data ) {
  1386 		if (
  1466 		if (
  1387 			! empty( $menu_item_data['menu-item-type'] ) &&
  1467 			! empty( $menu_item_data['menu-item-type'] ) &&
  1388 			'custom' != $menu_item_data['menu-item-type'] &&
  1468 			'custom' !== $menu_item_data['menu-item-type'] &&
  1389 			! empty( $menu_item_data['menu-item-object-id'] )
  1469 			! empty( $menu_item_data['menu-item-object-id'] )
  1390 		) {
  1470 		) {
  1391 			switch ( $menu_item_data['menu-item-type'] ) {
  1471 			switch ( $menu_item_data['menu-item-type'] ) {
  1392 				case 'post_type':
  1472 				case 'post_type':
  1393 					$_object = get_post( $menu_item_data['menu-item-object-id'] );
  1473 					$_object = get_post( $menu_item_data['menu-item-object-id'] );
  1403 			}
  1483 			}
  1404 
  1484 
  1405 			$_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
  1485 			$_menu_items = array_map( 'wp_setup_nav_menu_item', array( $_object ) );
  1406 			$_menu_item  = reset( $_menu_items );
  1486 			$_menu_item  = reset( $_menu_items );
  1407 
  1487 
  1408 			// Restore the missing menu item properties
  1488 			// Restore the missing menu item properties.
  1409 			$menu_item_data['menu-item-description'] = $_menu_item->description;
  1489 			$menu_item_data['menu-item-description'] = $_menu_item->description;
  1410 		}
  1490 		}
  1411 
  1491 
  1412 		$menu_items_data[] = $menu_item_data;
  1492 		$menu_items_data[] = $menu_item_data;
  1413 	}
  1493 	}
  1419 
  1499 
  1420 	$menu_items = array();
  1500 	$menu_items = array();
  1421 
  1501 
  1422 	foreach ( (array) $item_ids as $menu_item_id ) {
  1502 	foreach ( (array) $item_ids as $menu_item_id ) {
  1423 		$menu_obj = get_post( $menu_item_id );
  1503 		$menu_obj = get_post( $menu_item_id );
       
  1504 
  1424 		if ( ! empty( $menu_obj->ID ) ) {
  1505 		if ( ! empty( $menu_obj->ID ) ) {
  1425 			$menu_obj        = wp_setup_nav_menu_item( $menu_obj );
  1506 			$menu_obj        = wp_setup_nav_menu_item( $menu_obj );
  1426 			$menu_obj->title = empty( $menu_obj->title ) ? __( 'Menu Item' ) : $menu_obj->title;
  1507 			$menu_obj->title = empty( $menu_obj->title ) ? __( 'Menu Item' ) : $menu_obj->title;
  1427 			$menu_obj->label = $menu_obj->title; // don't show "(pending)" in ajax-added items
  1508 			$menu_obj->label = $menu_obj->title; // Don't show "(pending)" in ajax-added items.
  1428 			$menu_items[]    = $menu_obj;
  1509 			$menu_items[]    = $menu_obj;
  1429 		}
  1510 		}
  1430 	}
  1511 	}
  1431 
  1512 
  1432 	/** This filter is documented in wp-admin/includes/nav-menu.php */
  1513 	/** This filter is documented in wp-admin/includes/nav-menu.php */
  1442 			'before'      => '',
  1523 			'before'      => '',
  1443 			'link_after'  => '',
  1524 			'link_after'  => '',
  1444 			'link_before' => '',
  1525 			'link_before' => '',
  1445 			'walker'      => new $walker_class_name,
  1526 			'walker'      => new $walker_class_name,
  1446 		);
  1527 		);
       
  1528 
  1447 		echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
  1529 		echo walk_nav_menu_tree( $menu_items, 0, (object) $args );
  1448 	}
  1530 	}
       
  1531 
  1449 	wp_die();
  1532 	wp_die();
  1450 }
  1533 }
  1451 
  1534 
  1452 /**
  1535 /**
  1453  * Ajax handler for adding meta.
  1536  * Ajax handler for adding meta.
  1462 
  1545 
  1463 	if ( isset( $_POST['metakeyselect'] ) || isset( $_POST['metakeyinput'] ) ) {
  1546 	if ( isset( $_POST['metakeyselect'] ) || isset( $_POST['metakeyinput'] ) ) {
  1464 		if ( ! current_user_can( 'edit_post', $pid ) ) {
  1547 		if ( ! current_user_can( 'edit_post', $pid ) ) {
  1465 			wp_die( -1 );
  1548 			wp_die( -1 );
  1466 		}
  1549 		}
  1467 		if ( isset( $_POST['metakeyselect'] ) && '#NONE#' == $_POST['metakeyselect'] && empty( $_POST['metakeyinput'] ) ) {
  1550 
       
  1551 		if ( isset( $_POST['metakeyselect'] ) && '#NONE#' === $_POST['metakeyselect'] && empty( $_POST['metakeyinput'] ) ) {
  1468 			wp_die( 1 );
  1552 			wp_die( 1 );
  1469 		}
  1553 		}
  1470 
  1554 
  1471 		// If the post is an autodraft, save the post as a draft and then attempt to save the meta.
  1555 		// If the post is an autodraft, save the post as a draft and then attempt to save the meta.
  1472 		if ( $post->post_status == 'auto-draft' ) {
  1556 		if ( 'auto-draft' === $post->post_status ) {
  1473 			$post_data                = array();
  1557 			$post_data                = array();
  1474 			$post_data['action']      = 'draft'; // Warning fix
  1558 			$post_data['action']      = 'draft'; // Warning fix.
  1475 			$post_data['post_ID']     = $pid;
  1559 			$post_data['post_ID']     = $pid;
  1476 			$post_data['post_type']   = $post->post_type;
  1560 			$post_data['post_type']   = $post->post_type;
  1477 			$post_data['post_status'] = 'draft';
  1561 			$post_data['post_status'] = 'draft';
  1478 			$now                      = time();
  1562 			$now                      = time();
  1479 			/* translators: 1: Post creation date, 2: Post creation time */
  1563 			/* translators: 1: Post creation date, 2: Post creation time. */
  1480 			$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), date( __( 'F j, Y' ), $now ), date( __( 'g:i a' ), $now ) );
  1564 			$post_data['post_title'] = sprintf( __( 'Draft created on %1$s at %2$s' ), gmdate( __( 'F j, Y' ), $now ), gmdate( __( 'g:i a' ), $now ) );
  1481 
  1565 
  1482 			$pid = edit_post( $post_data );
  1566 			$pid = edit_post( $post_data );
       
  1567 
  1483 			if ( $pid ) {
  1568 			if ( $pid ) {
  1484 				if ( is_wp_error( $pid ) ) {
  1569 				if ( is_wp_error( $pid ) ) {
  1485 					$x = new WP_Ajax_Response(
  1570 					$x = new WP_Ajax_Response(
  1486 						array(
  1571 						array(
  1487 							'what' => 'meta',
  1572 							'what' => 'meta',
  1489 						)
  1574 						)
  1490 					);
  1575 					);
  1491 					$x->send();
  1576 					$x->send();
  1492 				}
  1577 				}
  1493 
  1578 
  1494 				if ( ! $mid = add_meta( $pid ) ) {
  1579 				$mid = add_meta( $pid );
       
  1580 				if ( ! $mid ) {
  1495 					wp_die( __( 'Please provide a custom field value.' ) );
  1581 					wp_die( __( 'Please provide a custom field value.' ) );
  1496 				}
  1582 				}
  1497 			} else {
  1583 			} else {
  1498 				wp_die( 0 );
  1584 				wp_die( 0 );
  1499 			}
  1585 			}
  1500 		} elseif ( ! $mid = add_meta( $pid ) ) {
  1586 		} else {
  1501 			wp_die( __( 'Please provide a custom field value.' ) );
  1587 			$mid = add_meta( $pid );
       
  1588 			if ( ! $mid ) {
       
  1589 				wp_die( __( 'Please provide a custom field value.' ) );
       
  1590 			}
  1502 		}
  1591 		}
  1503 
  1592 
  1504 		$meta = get_metadata_by_mid( 'post', $mid );
  1593 		$meta = get_metadata_by_mid( 'post', $mid );
  1505 		$pid  = (int) $meta->post_id;
  1594 		$pid  = (int) $meta->post_id;
  1506 		$meta = get_object_vars( $meta );
  1595 		$meta = get_object_vars( $meta );
  1507 		$x    = new WP_Ajax_Response(
  1596 
       
  1597 		$x = new WP_Ajax_Response(
  1508 			array(
  1598 			array(
  1509 				'what'         => 'meta',
  1599 				'what'         => 'meta',
  1510 				'id'           => $mid,
  1600 				'id'           => $mid,
  1511 				'data'         => _list_meta_row( $meta, $c ),
  1601 				'data'         => _list_meta_row( $meta, $c ),
  1512 				'position'     => 1,
  1602 				'position'     => 1,
  1515 		);
  1605 		);
  1516 	} else { // Update?
  1606 	} else { // Update?
  1517 		$mid   = (int) key( $_POST['meta'] );
  1607 		$mid   = (int) key( $_POST['meta'] );
  1518 		$key   = wp_unslash( $_POST['meta'][ $mid ]['key'] );
  1608 		$key   = wp_unslash( $_POST['meta'][ $mid ]['key'] );
  1519 		$value = wp_unslash( $_POST['meta'][ $mid ]['value'] );
  1609 		$value = wp_unslash( $_POST['meta'][ $mid ]['value'] );
  1520 		if ( '' == trim( $key ) ) {
  1610 
       
  1611 		if ( '' === trim( $key ) ) {
  1521 			wp_die( __( 'Please provide a custom field name.' ) );
  1612 			wp_die( __( 'Please provide a custom field name.' ) );
  1522 		}
  1613 		}
  1523 		if ( ! $meta = get_metadata_by_mid( 'post', $mid ) ) {
  1614 
  1524 			wp_die( 0 ); // if meta doesn't exist
  1615 		$meta = get_metadata_by_mid( 'post', $mid );
  1525 		}
  1616 
  1526 		if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
  1617 		if ( ! $meta ) {
       
  1618 			wp_die( 0 ); // If meta doesn't exist.
       
  1619 		}
       
  1620 
       
  1621 		if (
       
  1622 			is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
  1527 			! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
  1623 			! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
  1528 			! current_user_can( 'edit_post_meta', $meta->post_id, $key ) ) {
  1624 			! current_user_can( 'edit_post_meta', $meta->post_id, $key )
       
  1625 		) {
  1529 			wp_die( -1 );
  1626 			wp_die( -1 );
  1530 		}
  1627 		}
       
  1628 
  1531 		if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
  1629 		if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
  1532 			if ( ! $u = update_metadata_by_mid( 'post', $mid, $value, $key ) ) {
  1630 			$u = update_metadata_by_mid( 'post', $mid, $value, $key );
       
  1631 			if ( ! $u ) {
  1533 				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
  1632 				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
  1534 			}
  1633 			}
  1535 		}
  1634 		}
  1536 
  1635 
  1537 		$x = new WP_Ajax_Response(
  1636 		$x = new WP_Ajax_Response(
  1566 	if ( empty( $action ) ) {
  1665 	if ( empty( $action ) ) {
  1567 		$action = 'add-user';
  1666 		$action = 'add-user';
  1568 	}
  1667 	}
  1569 
  1668 
  1570 	check_ajax_referer( $action );
  1669 	check_ajax_referer( $action );
       
  1670 
  1571 	if ( ! current_user_can( 'create_users' ) ) {
  1671 	if ( ! current_user_can( 'create_users' ) ) {
  1572 		wp_die( -1 );
  1672 		wp_die( -1 );
  1573 	}
  1673 	}
  1574 	if ( ! $user_id = edit_user() ) {
  1674 
       
  1675 	$user_id = edit_user();
       
  1676 
       
  1677 	if ( ! $user_id ) {
  1575 		wp_die( 0 );
  1678 		wp_die( 0 );
  1576 	} elseif ( is_wp_error( $user_id ) ) {
  1679 	} elseif ( is_wp_error( $user_id ) ) {
  1577 		$x = new WP_Ajax_Response(
  1680 		$x = new WP_Ajax_Response(
  1578 			array(
  1681 			array(
  1579 				'what' => 'user',
  1682 				'what' => 'user',
  1580 				'id'   => $user_id,
  1683 				'id'   => $user_id,
  1581 			)
  1684 			)
  1582 		);
  1685 		);
  1583 		$x->send();
  1686 		$x->send();
  1584 	}
  1687 	}
  1585 	$user_object = get_userdata( $user_id );
  1688 
  1586 
  1689 	$user_object   = get_userdata( $user_id );
  1587 	$wp_list_table = _get_list_table( 'WP_Users_List_Table' );
  1690 	$wp_list_table = _get_list_table( 'WP_Users_List_Table' );
  1588 
  1691 
  1589 	$role = current( $user_object->roles );
  1692 	$role = current( $user_object->roles );
  1590 
  1693 
  1591 	$x = new WP_Ajax_Response(
  1694 	$x = new WP_Ajax_Response(
  1593 			'what'         => 'user',
  1696 			'what'         => 'user',
  1594 			'id'           => $user_id,
  1697 			'id'           => $user_id,
  1595 			'data'         => $wp_list_table->single_row( $user_object, '', $role ),
  1698 			'data'         => $wp_list_table->single_row( $user_object, '', $role ),
  1596 			'supplemental' => array(
  1699 			'supplemental' => array(
  1597 				'show-link' => sprintf(
  1700 				'show-link' => sprintf(
  1598 					/* translators: %s: the new user */
  1701 					/* translators: %s: The new user. */
  1599 					__( 'User %s added' ),
  1702 					__( 'User %s added' ),
  1600 					'<a href="#user-' . $user_id . '">' . $user_object->user_login . '</a>'
  1703 					'<a href="#user-' . $user_id . '">' . $user_object->user_login . '</a>'
  1601 				),
  1704 				),
  1602 				'role'      => $role,
  1705 				'role'      => $role,
  1603 			),
  1706 			),
  1619 	$hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1722 	$hidden = isset( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1620 	$hidden = array_filter( $hidden );
  1723 	$hidden = array_filter( $hidden );
  1621 
  1724 
  1622 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1725 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1623 
  1726 
  1624 	if ( $page != sanitize_key( $page ) ) {
  1727 	if ( sanitize_key( $page ) != $page ) {
  1625 		wp_die( 0 );
  1728 		wp_die( 0 );
  1626 	}
  1729 	}
  1627 
  1730 
  1628 	if ( ! $user = wp_get_current_user() ) {
  1731 	$user = wp_get_current_user();
       
  1732 	if ( ! $user ) {
  1629 		wp_die( -1 );
  1733 		wp_die( -1 );
  1630 	}
  1734 	}
  1631 
  1735 
  1632 	if ( is_array( $closed ) ) {
  1736 	if ( is_array( $closed ) ) {
  1633 		update_user_option( $user->ID, "closedpostboxes_$page", $closed, true );
  1737 		update_user_option( $user->ID, "closedpostboxes_$page", $closed, true );
  1634 	}
  1738 	}
  1635 
  1739 
  1636 	if ( is_array( $hidden ) ) {
  1740 	if ( is_array( $hidden ) ) {
  1637 		$hidden = array_diff( $hidden, array( 'submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu' ) ); // postboxes that are always shown
  1741 		// Postboxes that are always shown.
       
  1742 		$hidden = array_diff( $hidden, array( 'submitdiv', 'linksubmitdiv', 'manage-menu', 'create-menu' ) );
  1638 		update_user_option( $user->ID, "metaboxhidden_$page", $hidden, true );
  1743 		update_user_option( $user->ID, "metaboxhidden_$page", $hidden, true );
  1639 	}
  1744 	}
  1640 
  1745 
  1641 	wp_die( 1 );
  1746 	wp_die( 1 );
  1642 }
  1747 }
  1648  */
  1753  */
  1649 function wp_ajax_hidden_columns() {
  1754 function wp_ajax_hidden_columns() {
  1650 	check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
  1755 	check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
  1651 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1756 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1652 
  1757 
  1653 	if ( $page != sanitize_key( $page ) ) {
  1758 	if ( sanitize_key( $page ) != $page ) {
  1654 		wp_die( 0 );
  1759 		wp_die( 0 );
  1655 	}
  1760 	}
  1656 
  1761 
  1657 	if ( ! $user = wp_get_current_user() ) {
  1762 	$user = wp_get_current_user();
       
  1763 	if ( ! $user ) {
  1658 		wp_die( -1 );
  1764 		wp_die( -1 );
  1659 	}
  1765 	}
  1660 
  1766 
  1661 	$hidden = ! empty( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1767 	$hidden = ! empty( $_POST['hidden'] ) ? explode( ',', $_POST['hidden'] ) : array();
  1662 	update_user_option( $user->ID, "manage{$page}columnshidden", $hidden, true );
  1768 	update_user_option( $user->ID, "manage{$page}columnshidden", $hidden, true );
  1691 		wp_die( -1 );
  1797 		wp_die( -1 );
  1692 	}
  1798 	}
  1693 
  1799 
  1694 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1800 	require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
  1695 
  1801 
  1696 	if ( isset( $_POST['item-type'] ) && 'post_type' == $_POST['item-type'] ) {
  1802 	if ( isset( $_POST['item-type'] ) && 'post_type' === $_POST['item-type'] ) {
  1697 		$type     = 'posttype';
  1803 		$type     = 'posttype';
  1698 		$callback = 'wp_nav_menu_item_post_type_meta_box';
  1804 		$callback = 'wp_nav_menu_item_post_type_meta_box';
  1699 		$items    = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
  1805 		$items    = (array) get_post_types( array( 'show_in_nav_menus' => true ), 'object' );
  1700 	} elseif ( isset( $_POST['item-type'] ) && 'taxonomy' == $_POST['item-type'] ) {
  1806 	} elseif ( isset( $_POST['item-type'] ) && 'taxonomy' === $_POST['item-type'] ) {
  1701 		$type     = 'taxonomy';
  1807 		$type     = 'taxonomy';
  1702 		$callback = 'wp_nav_menu_item_taxonomy_meta_box';
  1808 		$callback = 'wp_nav_menu_item_taxonomy_meta_box';
  1703 		$items    = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
  1809 		$items    = (array) get_taxonomies( array( 'show_ui' => true ), 'object' );
  1704 	}
  1810 	}
  1705 
  1811 
  1706 	if ( ! empty( $_POST['item-object'] ) && isset( $items[ $_POST['item-object'] ] ) ) {
  1812 	if ( ! empty( $_POST['item-object'] ) && isset( $items[ $_POST['item-object'] ] ) ) {
  1707 		$menus_meta_box_object = $items[ $_POST['item-object'] ];
  1813 		$menus_meta_box_object = $items[ $_POST['item-object'] ];
  1708 
  1814 
  1709 		/** This filter is documented in wp-admin/includes/nav-menu.php */
  1815 		/** This filter is documented in wp-admin/includes/nav-menu.php */
  1710 		$item = apply_filters( 'nav_menu_meta_box_object', $menus_meta_box_object );
  1816 		$item = apply_filters( 'nav_menu_meta_box_object', $menus_meta_box_object );
       
  1817 
       
  1818 		$box_args = array(
       
  1819 			'id'       => 'add-' . $item->name,
       
  1820 			'title'    => $item->labels->name,
       
  1821 			'callback' => $callback,
       
  1822 			'args'     => $item,
       
  1823 		);
       
  1824 
  1711 		ob_start();
  1825 		ob_start();
  1712 		call_user_func_array(
  1826 		$callback( null, $box_args );
  1713 			$callback,
       
  1714 			array(
       
  1715 				null,
       
  1716 				array(
       
  1717 					'id'       => 'add-' . $item->name,
       
  1718 					'title'    => $item->labels->name,
       
  1719 					'callback' => $callback,
       
  1720 					'args'     => $item,
       
  1721 				),
       
  1722 			)
       
  1723 		);
       
  1724 
  1827 
  1725 		$markup = ob_get_clean();
  1828 		$markup = ob_get_clean();
  1726 
  1829 
  1727 		echo wp_json_encode(
  1830 		echo wp_json_encode(
  1728 			array(
  1831 			array(
  1754 	}
  1857 	}
  1755 
  1858 
  1756 	$args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
  1859 	$args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
  1757 
  1860 
  1758 	if ( ! class_exists( '_WP_Editors', false ) ) {
  1861 	if ( ! class_exists( '_WP_Editors', false ) ) {
  1759 		require( ABSPATH . WPINC . '/class-wp-editor.php' );
  1862 		require ABSPATH . WPINC . '/class-wp-editor.php';
  1760 	}
  1863 	}
  1761 
  1864 
  1762 	$results = _WP_Editors::wp_link_query( $args );
  1865 	$results = _WP_Editors::wp_link_query( $args );
  1763 
  1866 
  1764 	if ( ! isset( $results ) ) {
  1867 	if ( ! isset( $results ) ) {
  1778  */
  1881  */
  1779 function wp_ajax_menu_locations_save() {
  1882 function wp_ajax_menu_locations_save() {
  1780 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1883 	if ( ! current_user_can( 'edit_theme_options' ) ) {
  1781 		wp_die( -1 );
  1884 		wp_die( -1 );
  1782 	}
  1885 	}
       
  1886 
  1783 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
  1887 	check_ajax_referer( 'add-menu_item', 'menu-settings-column-nonce' );
       
  1888 
  1784 	if ( ! isset( $_POST['menu-locations'] ) ) {
  1889 	if ( ! isset( $_POST['menu-locations'] ) ) {
  1785 		wp_die( 0 );
  1890 		wp_die( 0 );
  1786 	}
  1891 	}
       
  1892 
  1787 	set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
  1893 	set_theme_mod( 'nav_menu_locations', array_map( 'absint', $_POST['menu-locations'] ) );
  1788 	wp_die( 1 );
  1894 	wp_die( 1 );
  1789 }
  1895 }
  1790 
  1896 
  1791 /**
  1897 /**
  1796 function wp_ajax_meta_box_order() {
  1902 function wp_ajax_meta_box_order() {
  1797 	check_ajax_referer( 'meta-box-order' );
  1903 	check_ajax_referer( 'meta-box-order' );
  1798 	$order        = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
  1904 	$order        = isset( $_POST['order'] ) ? (array) $_POST['order'] : false;
  1799 	$page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
  1905 	$page_columns = isset( $_POST['page_columns'] ) ? $_POST['page_columns'] : 'auto';
  1800 
  1906 
  1801 	if ( $page_columns != 'auto' ) {
  1907 	if ( 'auto' !== $page_columns ) {
  1802 		$page_columns = (int) $page_columns;
  1908 		$page_columns = (int) $page_columns;
  1803 	}
  1909 	}
  1804 
  1910 
  1805 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1911 	$page = isset( $_POST['page'] ) ? $_POST['page'] : '';
  1806 
  1912 
  1807 	if ( $page != sanitize_key( $page ) ) {
  1913 	if ( sanitize_key( $page ) != $page ) {
  1808 		wp_die( 0 );
  1914 		wp_die( 0 );
  1809 	}
  1915 	}
  1810 
  1916 
  1811 	if ( ! $user = wp_get_current_user() ) {
  1917 	$user = wp_get_current_user();
       
  1918 	if ( ! $user ) {
  1812 		wp_die( -1 );
  1919 		wp_die( -1 );
  1813 	}
  1920 	}
  1814 
  1921 
  1815 	if ( $order ) {
  1922 	if ( $order ) {
  1816 		update_user_option( $user->ID, "meta-box-order_$page", $order, true );
  1923 		update_user_option( $user->ID, "meta-box-order_$page", $order, true );
  1818 
  1925 
  1819 	if ( $page_columns ) {
  1926 	if ( $page_columns ) {
  1820 		update_user_option( $user->ID, "screen_layout_$page", $page_columns, true );
  1927 		update_user_option( $user->ID, "screen_layout_$page", $page_columns, true );
  1821 	}
  1928 	}
  1822 
  1929 
  1823 	wp_die( 1 );
  1930 	wp_send_json_success();
  1824 }
  1931 }
  1825 
  1932 
  1826 /**
  1933 /**
  1827  * Ajax handler for menu quick searching.
  1934  * Ajax handler for menu quick searching.
  1828  *
  1935  *
  1874 function wp_ajax_inline_save() {
  1981 function wp_ajax_inline_save() {
  1875 	global $mode;
  1982 	global $mode;
  1876 
  1983 
  1877 	check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
  1984 	check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
  1878 
  1985 
  1879 	if ( ! isset( $_POST['post_ID'] ) || ! ( $post_ID = (int) $_POST['post_ID'] ) ) {
  1986 	if ( ! isset( $_POST['post_ID'] ) || ! (int) $_POST['post_ID'] ) {
  1880 		wp_die();
  1987 		wp_die();
  1881 	}
  1988 	}
  1882 
  1989 
  1883 	if ( 'page' == $_POST['post_type'] ) {
  1990 	$post_ID = (int) $_POST['post_ID'];
       
  1991 
       
  1992 	if ( 'page' === $_POST['post_type'] ) {
  1884 		if ( ! current_user_can( 'edit_page', $post_ID ) ) {
  1993 		if ( ! current_user_can( 'edit_page', $post_ID ) ) {
  1885 			wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
  1994 			wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
  1886 		}
  1995 		}
  1887 	} else {
  1996 	} else {
  1888 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  1997 		if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  1889 			wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  1998 			wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
  1890 		}
  1999 		}
  1891 	}
  2000 	}
  1892 
  2001 
  1893 	if ( $last = wp_check_post_lock( $post_ID ) ) {
  2002 	$last = wp_check_post_lock( $post_ID );
       
  2003 	if ( $last ) {
  1894 		$last_user      = get_userdata( $last );
  2004 		$last_user      = get_userdata( $last );
  1895 		$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
  2005 		$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
  1896 
  2006 
  1897 		/* translators: %s: user who is currently editing the post */
  2007 		/* translators: %s: User's display name. */
  1898 		$msg_template = __( 'Saving is disabled: %s is currently editing this post.' );
  2008 		$msg_template = __( 'Saving is disabled: %s is currently editing this post.' );
  1899 		if ( $_POST['post_type'] == 'page' ) {
  2009 
  1900 			/* translators: %s: user who is currently editing the page */
  2010 		if ( 'page' === $_POST['post_type'] ) {
       
  2011 			/* translators: %s: User's display name. */
  1901 			$msg_template = __( 'Saving is disabled: %s is currently editing this page.' );
  2012 			$msg_template = __( 'Saving is disabled: %s is currently editing this page.' );
  1902 		}
  2013 		}
  1903 
  2014 
  1904 		printf( $msg_template, esc_html( $last_user_name ) );
  2015 		printf( $msg_template, esc_html( $last_user_name ) );
  1905 		wp_die();
  2016 		wp_die();
  1921 	if ( isset( $data['post_parent'] ) ) {
  2032 	if ( isset( $data['post_parent'] ) ) {
  1922 		$data['parent_id'] = $data['post_parent'];
  2033 		$data['parent_id'] = $data['post_parent'];
  1923 	}
  2034 	}
  1924 
  2035 
  1925 	// Status.
  2036 	// Status.
  1926 	if ( isset( $data['keep_private'] ) && 'private' == $data['keep_private'] ) {
  2037 	if ( isset( $data['keep_private'] ) && 'private' === $data['keep_private'] ) {
  1927 		$data['visibility']  = 'private';
  2038 		$data['visibility']  = 'private';
  1928 		$data['post_status'] = 'private';
  2039 		$data['post_status'] = 'private';
  1929 	} else {
  2040 	} else {
  1930 		$data['post_status'] = $data['_status'];
  2041 		$data['post_status'] = $data['_status'];
  1931 	}
  2042 	}
  1932 
  2043 
  1933 	if ( empty( $data['comment_status'] ) ) {
  2044 	if ( empty( $data['comment_status'] ) ) {
  1934 		$data['comment_status'] = 'closed';
  2045 		$data['comment_status'] = 'closed';
  1935 	}
  2046 	}
       
  2047 
  1936 	if ( empty( $data['ping_status'] ) ) {
  2048 	if ( empty( $data['ping_status'] ) ) {
  1937 		$data['ping_status'] = 'closed';
  2049 		$data['ping_status'] = 'closed';
  1938 	}
  2050 	}
  1939 
  2051 
  1940 	// Exclude terms from taxonomies that are not supposed to appear in Quick Edit.
  2052 	// Exclude terms from taxonomies that are not supposed to appear in Quick Edit.
  1947 			}
  2059 			}
  1948 		}
  2060 		}
  1949 	}
  2061 	}
  1950 
  2062 
  1951 	// Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
  2063 	// Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
  1952 	if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
  2064 	if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ), true ) ) {
  1953 		$post['post_status'] = 'publish';
  2065 		$post['post_status'] = 'publish';
  1954 		$data['post_name']   = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
  2066 		$data['post_name']   = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
  1955 	}
  2067 	}
  1956 
  2068 
  1957 	// Update the post.
  2069 	// Update the post.
  1958 	edit_post();
  2070 	edit_post();
  1959 
  2071 
  1960 	$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
  2072 	$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );
  1961 
  2073 
  1962 	$mode = $_POST['post_view'] === 'excerpt' ? 'excerpt' : 'list';
  2074 	$mode = 'excerpt' === $_POST['post_view'] ? 'excerpt' : 'list';
  1963 
  2075 
  1964 	$level = 0;
  2076 	$level = 0;
  1965 	if ( is_post_type_hierarchical( $wp_list_table->screen->post_type ) ) {
  2077 	if ( is_post_type_hierarchical( $wp_list_table->screen->post_type ) ) {
  1966 		$request_post = array( get_post( $_POST['post_ID'] ) );
  2078 		$request_post = array( get_post( $_POST['post_ID'] ) );
  1967 		$parent       = $request_post[0]->post_parent;
  2079 		$parent       = $request_post[0]->post_parent;
  1986 function wp_ajax_inline_save_tax() {
  2098 function wp_ajax_inline_save_tax() {
  1987 	check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
  2099 	check_ajax_referer( 'taxinlineeditnonce', '_inline_edit' );
  1988 
  2100 
  1989 	$taxonomy = sanitize_key( $_POST['taxonomy'] );
  2101 	$taxonomy = sanitize_key( $_POST['taxonomy'] );
  1990 	$tax      = get_taxonomy( $taxonomy );
  2102 	$tax      = get_taxonomy( $taxonomy );
       
  2103 
  1991 	if ( ! $tax ) {
  2104 	if ( ! $tax ) {
  1992 		wp_die( 0 );
  2105 		wp_die( 0 );
  1993 	}
  2106 	}
  1994 
  2107 
  1995 	if ( ! isset( $_POST['tax_ID'] ) || ! ( $id = (int) $_POST['tax_ID'] ) ) {
  2108 	if ( ! isset( $_POST['tax_ID'] ) || ! (int) $_POST['tax_ID'] ) {
  1996 		wp_die( -1 );
  2109 		wp_die( -1 );
  1997 	}
  2110 	}
       
  2111 
       
  2112 	$id = (int) $_POST['tax_ID'];
  1998 
  2113 
  1999 	if ( ! current_user_can( 'edit_term', $id ) ) {
  2114 	if ( ! current_user_can( 'edit_term', $id ) ) {
  2000 		wp_die( -1 );
  2115 		wp_die( -1 );
  2001 	}
  2116 	}
  2002 
  2117 
  2004 
  2119 
  2005 	$tag                  = get_term( $id, $taxonomy );
  2120 	$tag                  = get_term( $id, $taxonomy );
  2006 	$_POST['description'] = $tag->description;
  2121 	$_POST['description'] = $tag->description;
  2007 
  2122 
  2008 	$updated = wp_update_term( $id, $taxonomy, $_POST );
  2123 	$updated = wp_update_term( $id, $taxonomy, $_POST );
       
  2124 
  2009 	if ( $updated && ! is_wp_error( $updated ) ) {
  2125 	if ( $updated && ! is_wp_error( $updated ) ) {
  2010 		$tag = get_term( $updated['term_id'], $taxonomy );
  2126 		$tag = get_term( $updated['term_id'], $taxonomy );
  2011 		if ( ! $tag || is_wp_error( $tag ) ) {
  2127 		if ( ! $tag || is_wp_error( $tag ) ) {
  2012 			if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  2128 			if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
  2013 				wp_die( $tag->get_error_message() );
  2129 				wp_die( $tag->get_error_message() );
  2018 		if ( is_wp_error( $updated ) && $updated->get_error_message() ) {
  2134 		if ( is_wp_error( $updated ) && $updated->get_error_message() ) {
  2019 			wp_die( $updated->get_error_message() );
  2135 			wp_die( $updated->get_error_message() );
  2020 		}
  2136 		}
  2021 		wp_die( __( 'Item not updated.' ) );
  2137 		wp_die( __( 'Item not updated.' ) );
  2022 	}
  2138 	}
       
  2139 
  2023 	$level  = 0;
  2140 	$level  = 0;
  2024 	$parent = $tag->parent;
  2141 	$parent = $tag->parent;
       
  2142 
  2025 	while ( $parent > 0 ) {
  2143 	while ( $parent > 0 ) {
  2026 		$parent_tag = get_term( $parent, $taxonomy );
  2144 		$parent_tag = get_term( $parent, $taxonomy );
  2027 		$parent     = $parent_tag->parent;
  2145 		$parent     = $parent_tag->parent;
  2028 		$level++;
  2146 		$level++;
  2029 	}
  2147 	}
       
  2148 
  2030 	$wp_list_table->single_row( $tag, $level );
  2149 	$wp_list_table->single_row( $tag, $level );
  2031 	wp_die();
  2150 	wp_die();
  2032 }
  2151 }
  2033 
  2152 
  2034 /**
  2153 /**
  2048 	$args = array(
  2167 	$args = array(
  2049 		'post_type'      => array_keys( $post_types ),
  2168 		'post_type'      => array_keys( $post_types ),
  2050 		'post_status'    => 'any',
  2169 		'post_status'    => 'any',
  2051 		'posts_per_page' => 50,
  2170 		'posts_per_page' => 50,
  2052 	);
  2171 	);
       
  2172 
  2053 	if ( '' !== $s ) {
  2173 	if ( '' !== $s ) {
  2054 		$args['s'] = $s;
  2174 		$args['s'] = $s;
  2055 	}
  2175 	}
  2056 
  2176 
  2057 	$posts = get_posts( $args );
  2177 	$posts = get_posts( $args );
  2062 
  2182 
  2063 	$html = '<table class="widefat"><thead><tr><th class="found-radio"><br /></th><th>' . __( 'Title' ) . '</th><th class="no-break">' . __( 'Type' ) . '</th><th class="no-break">' . __( 'Date' ) . '</th><th class="no-break">' . __( 'Status' ) . '</th></tr></thead><tbody>';
  2183 	$html = '<table class="widefat"><thead><tr><th class="found-radio"><br /></th><th>' . __( 'Title' ) . '</th><th class="no-break">' . __( 'Type' ) . '</th><th class="no-break">' . __( 'Date' ) . '</th><th class="no-break">' . __( 'Status' ) . '</th></tr></thead><tbody>';
  2064 	$alt  = '';
  2184 	$alt  = '';
  2065 	foreach ( $posts as $post ) {
  2185 	foreach ( $posts as $post ) {
  2066 		$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
  2186 		$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
  2067 		$alt   = ( 'alternate' == $alt ) ? '' : 'alternate';
  2187 		$alt   = ( 'alternate' === $alt ) ? '' : 'alternate';
  2068 
  2188 
  2069 		switch ( $post->post_status ) {
  2189 		switch ( $post->post_status ) {
  2070 			case 'publish':
  2190 			case 'publish':
  2071 			case 'private':
  2191 			case 'private':
  2072 				$stat = __( 'Published' );
  2192 				$stat = __( 'Published' );
  2080 			case 'draft':
  2200 			case 'draft':
  2081 				$stat = __( 'Draft' );
  2201 				$stat = __( 'Draft' );
  2082 				break;
  2202 				break;
  2083 		}
  2203 		}
  2084 
  2204 
  2085 		if ( '0000-00-00 00:00:00' == $post->post_date ) {
  2205 		if ( '0000-00-00 00:00:00' === $post->post_date ) {
  2086 			$time = '';
  2206 			$time = '';
  2087 		} else {
  2207 		} else {
  2088 			/* translators: date format in table columns, see https://secure.php.net/date */
  2208 			/* translators: Date format in table columns, see https://www.php.net/date */
  2089 			$time = mysql2date( __( 'Y/m/d' ), $post->post_date );
  2209 			$time = mysql2date( __( 'Y/m/d' ), $post->post_date );
  2090 		}
  2210 		}
  2091 
  2211 
  2092 		$html .= '<tr class="' . trim( 'found-posts ' . $alt ) . '"><td class="found-radio"><input type="radio" id="found-' . $post->ID . '" name="found_post_id" value="' . esc_attr( $post->ID ) . '"></td>';
  2212 		$html .= '<tr class="' . trim( 'found-posts ' . $alt ) . '"><td class="found-radio"><input type="radio" id="found-' . $post->ID . '" name="found_post_id" value="' . esc_attr( $post->ID ) . '"></td>';
  2093 		$html .= '<td><label for="found-' . $post->ID . '">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[ $post->post_type ]->labels->singular_name ) . '</td><td class="no-break">' . esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ) . ' </td></tr>' . "\n\n";
  2213 		$html .= '<td><label for="found-' . $post->ID . '">' . esc_html( $title ) . '</label></td><td class="no-break">' . esc_html( $post_types[ $post->post_type ]->labels->singular_name ) . '</td><td class="no-break">' . esc_html( $time ) . '</td><td class="no-break">' . esc_html( $stat ) . ' </td></tr>' . "\n\n";
  2113 	unset( $_POST['savewidgets'], $_POST['action'] );
  2233 	unset( $_POST['savewidgets'], $_POST['action'] );
  2114 
  2234 
  2115 	// Save widgets order for all sidebars.
  2235 	// Save widgets order for all sidebars.
  2116 	if ( is_array( $_POST['sidebars'] ) ) {
  2236 	if ( is_array( $_POST['sidebars'] ) ) {
  2117 		$sidebars = array();
  2237 		$sidebars = array();
       
  2238 
  2118 		foreach ( wp_unslash( $_POST['sidebars'] ) as $key => $val ) {
  2239 		foreach ( wp_unslash( $_POST['sidebars'] ) as $key => $val ) {
  2119 			$sb = array();
  2240 			$sb = array();
       
  2241 
  2120 			if ( ! empty( $val ) ) {
  2242 			if ( ! empty( $val ) ) {
  2121 				$val = explode( ',', $val );
  2243 				$val = explode( ',', $val );
       
  2244 
  2122 				foreach ( $val as $k => $v ) {
  2245 				foreach ( $val as $k => $v ) {
  2123 					if ( strpos( $v, 'widget-' ) === false ) {
  2246 					if ( strpos( $v, 'widget-' ) === false ) {
  2124 						continue;
  2247 						continue;
  2125 					}
  2248 					}
  2126 
  2249 
  2127 					$sb[ $k ] = substr( $v, strpos( $v, '_' ) + 1 );
  2250 					$sb[ $k ] = substr( $v, strpos( $v, '_' ) + 1 );
  2128 				}
  2251 				}
  2129 			}
  2252 			}
  2130 			$sidebars[ $key ] = $sb;
  2253 			$sidebars[ $key ] = $sb;
  2131 		}
  2254 		}
       
  2255 
  2132 		wp_set_sidebars_widgets( $sidebars );
  2256 		wp_set_sidebars_widgets( $sidebars );
  2133 		wp_die( 1 );
  2257 		wp_die( 1 );
  2134 	}
  2258 	}
  2135 
  2259 
  2136 	wp_die( -1 );
  2260 	wp_die( -1 );
  2159 	/**
  2283 	/**
  2160 	 * Fires early when editing the widgets displayed in sidebars.
  2284 	 * Fires early when editing the widgets displayed in sidebars.
  2161 	 *
  2285 	 *
  2162 	 * @since 2.8.0
  2286 	 * @since 2.8.0
  2163 	 */
  2287 	 */
  2164 	do_action( 'load-widgets.php' );
  2288 	do_action( 'load-widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
  2165 
  2289 
  2166 	/**
  2290 	/**
  2167 	 * Fires early when editing the widgets displayed in sidebars.
  2291 	 * Fires early when editing the widgets displayed in sidebars.
  2168 	 *
  2292 	 *
  2169 	 * @since 2.8.0
  2293 	 * @since 2.8.0
  2170 	 */
  2294 	 */
  2171 	do_action( 'widgets.php' );
  2295 	do_action( 'widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
  2172 
  2296 
  2173 	/** This action is documented in wp-admin/widgets.php */
  2297 	/** This action is documented in wp-admin/widgets.php */
  2174 	do_action( 'sidebar_admin_setup' );
  2298 	do_action( 'sidebar_admin_setup' );
  2175 
  2299 
  2176 	$id_base      = wp_unslash( $_POST['id_base'] );
  2300 	$id_base      = wp_unslash( $_POST['id_base'] );
  2235 
  2359 
  2236 	if ( ! empty( $_POST['add_new'] ) ) {
  2360 	if ( ! empty( $_POST['add_new'] ) ) {
  2237 		wp_die();
  2361 		wp_die();
  2238 	}
  2362 	}
  2239 
  2363 
  2240 	if ( $form = $wp_registered_widget_controls[ $widget_id ] ) {
  2364 	$form = $wp_registered_widget_controls[ $widget_id ];
       
  2365 	if ( $form ) {
  2241 		call_user_func_array( $form['callback'], $form['params'] );
  2366 		call_user_func_array( $form['callback'], $form['params'] );
  2242 	}
  2367 	}
  2243 
  2368 
  2244 	wp_die();
  2369 	wp_die();
  2245 }
  2370 }
  2268 		wp_die( -1 );
  2393 		wp_die( -1 );
  2269 	}
  2394 	}
  2270 
  2395 
  2271 	unset( $_POST['removeinactivewidgets'], $_POST['action'] );
  2396 	unset( $_POST['removeinactivewidgets'], $_POST['action'] );
  2272 	/** This action is documented in wp-admin/includes/ajax-actions.php */
  2397 	/** This action is documented in wp-admin/includes/ajax-actions.php */
  2273 	do_action( 'load-widgets.php' );
  2398 	do_action( 'load-widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
  2274 	/** This action is documented in wp-admin/includes/ajax-actions.php */
  2399 	/** This action is documented in wp-admin/includes/ajax-actions.php */
  2275 	do_action( 'widgets.php' );
  2400 	do_action( 'widgets.php' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
  2276 	/** This action is documented in wp-admin/widgets.php */
  2401 	/** This action is documented in wp-admin/widgets.php */
  2277 	do_action( 'sidebar_admin_setup' );
  2402 	do_action( 'sidebar_admin_setup' );
  2278 
  2403 
  2279 	$sidebars_widgets = wp_get_sidebars_widgets();
  2404 	$sidebars_widgets = wp_get_sidebars_widgets();
  2280 
  2405 
  2289 	}
  2414 	}
  2290 
  2415 
  2291 	wp_set_sidebars_widgets( $sidebars_widgets );
  2416 	wp_set_sidebars_widgets( $sidebars_widgets );
  2292 
  2417 
  2293 	wp_die();
  2418 	wp_die();
       
  2419 }
       
  2420 
       
  2421 /**
       
  2422  * Ajax handler for creating missing image sub-sizes for just uploaded images.
       
  2423  *
       
  2424  * @since 5.3.0
       
  2425  */
       
  2426 function wp_ajax_media_create_image_subsizes() {
       
  2427 	check_ajax_referer( 'media-form' );
       
  2428 
       
  2429 	if ( ! current_user_can( 'upload_files' ) ) {
       
  2430 		wp_send_json_error( array( 'message' => __( 'Sorry, you are not allowed to upload files.' ) ) );
       
  2431 	}
       
  2432 
       
  2433 	if ( empty( $_POST['attachment_id'] ) ) {
       
  2434 		wp_send_json_error( array( 'message' => __( 'Upload failed. Please reload and try again.' ) ) );
       
  2435 	}
       
  2436 
       
  2437 	$attachment_id = (int) $_POST['attachment_id'];
       
  2438 
       
  2439 	if ( ! empty( $_POST['_wp_upload_failed_cleanup'] ) ) {
       
  2440 		// Upload failed. Cleanup.
       
  2441 		if ( wp_attachment_is_image( $attachment_id ) && current_user_can( 'delete_post', $attachment_id ) ) {
       
  2442 			$attachment = get_post( $attachment_id );
       
  2443 
       
  2444 			// Created at most 10 min ago.
       
  2445 			if ( $attachment && ( time() - strtotime( $attachment->post_date_gmt ) < 600 ) ) {
       
  2446 				wp_delete_attachment( $attachment_id, true );
       
  2447 				wp_send_json_success();
       
  2448 			}
       
  2449 		}
       
  2450 	}
       
  2451 
       
  2452 	// Set a custom header with the attachment_id.
       
  2453 	// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
       
  2454 	if ( ! headers_sent() ) {
       
  2455 		header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
       
  2456 	}
       
  2457 
       
  2458 	// This can still be pretty slow and cause timeout or out of memory errors.
       
  2459 	// The js that handles the response would need to also handle HTTP 500 errors.
       
  2460 	wp_update_image_subsizes( $attachment_id );
       
  2461 
       
  2462 	if ( ! empty( $_POST['_legacy_support'] ) ) {
       
  2463 		// The old (inline) uploader. Only needs the attachment_id.
       
  2464 		$response = array( 'id' => $attachment_id );
       
  2465 	} else {
       
  2466 		// Media modal and Media Library grid view.
       
  2467 		$response = wp_prepare_attachment_for_js( $attachment_id );
       
  2468 
       
  2469 		if ( ! $response ) {
       
  2470 			wp_send_json_error( array( 'message' => __( 'Upload failed.' ) ) );
       
  2471 		}
       
  2472 	}
       
  2473 
       
  2474 	// At this point the image has been uploaded successfully.
       
  2475 	wp_send_json_success( $response );
  2294 }
  2476 }
  2295 
  2477 
  2296 /**
  2478 /**
  2297  * Ajax handler for uploading attachments
  2479  * Ajax handler for uploading attachments
  2298  *
  2480  *
  2320 		wp_die();
  2502 		wp_die();
  2321 	}
  2503 	}
  2322 
  2504 
  2323 	if ( isset( $_REQUEST['post_id'] ) ) {
  2505 	if ( isset( $_REQUEST['post_id'] ) ) {
  2324 		$post_id = $_REQUEST['post_id'];
  2506 		$post_id = $_REQUEST['post_id'];
       
  2507 
  2325 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2508 		if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2326 			echo wp_json_encode(
  2509 			echo wp_json_encode(
  2327 				array(
  2510 				array(
  2328 					'success' => false,
  2511 					'success' => false,
  2329 					'data'    => array(
  2512 					'data'    => array(
  2344 	if ( is_wp_error( $post_data ) ) {
  2527 	if ( is_wp_error( $post_data ) ) {
  2345 		wp_die( $post_data->get_error_message() );
  2528 		wp_die( $post_data->get_error_message() );
  2346 	}
  2529 	}
  2347 
  2530 
  2348 	// If the context is custom header or background, make sure the uploaded file is an image.
  2531 	// If the context is custom header or background, make sure the uploaded file is an image.
  2349 	if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
  2532 	if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ), true ) ) {
  2350 		$wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
  2533 		$wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
       
  2534 
  2351 		if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
  2535 		if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
  2352 			echo wp_json_encode(
  2536 			echo wp_json_encode(
  2353 				array(
  2537 				array(
  2354 					'success' => false,
  2538 					'success' => false,
  2355 					'data'    => array(
  2539 					'data'    => array(
  2387 		if ( 'custom-header' === $post_data['context'] ) {
  2571 		if ( 'custom-header' === $post_data['context'] ) {
  2388 			update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
  2572 			update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
  2389 		}
  2573 		}
  2390 	}
  2574 	}
  2391 
  2575 
  2392 	if ( ! $attachment = wp_prepare_attachment_for_js( $attachment_id ) ) {
  2576 	$attachment = wp_prepare_attachment_for_js( $attachment_id );
       
  2577 	if ( ! $attachment ) {
  2393 		wp_die();
  2578 		wp_die();
  2394 	}
  2579 	}
  2395 
  2580 
  2396 	echo wp_json_encode(
  2581 	echo wp_json_encode(
  2397 		array(
  2582 		array(
  2408  *
  2593  *
  2409  * @since 3.1.0
  2594  * @since 3.1.0
  2410  */
  2595  */
  2411 function wp_ajax_image_editor() {
  2596 function wp_ajax_image_editor() {
  2412 	$attachment_id = intval( $_POST['postid'] );
  2597 	$attachment_id = intval( $_POST['postid'] );
       
  2598 
  2413 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  2599 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  2414 		wp_die( -1 );
  2600 		wp_die( -1 );
  2415 	}
  2601 	}
  2416 
  2602 
  2417 	check_ajax_referer( "image_editor-$attachment_id" );
  2603 	check_ajax_referer( "image_editor-$attachment_id" );
  2418 	include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
  2604 	include_once ABSPATH . 'wp-admin/includes/image-edit.php';
  2419 
  2605 
  2420 	$msg = false;
  2606 	$msg = false;
  2421 	switch ( $_POST['do'] ) {
  2607 	switch ( $_POST['do'] ) {
  2422 		case 'save':
  2608 		case 'save':
  2423 			$msg = wp_save_image( $attachment_id );
  2609 			$msg = wp_save_image( $attachment_id );
  2424 			$msg = wp_json_encode( $msg );
  2610 			if ( $msg->error ) {
  2425 			wp_die( $msg );
  2611 				wp_send_json_error( $msg );
       
  2612 			}
       
  2613 
       
  2614 			wp_send_json_success( $msg );
  2426 			break;
  2615 			break;
  2427 		case 'scale':
  2616 		case 'scale':
  2428 			$msg = wp_save_image( $attachment_id );
  2617 			$msg = wp_save_image( $attachment_id );
  2429 			break;
  2618 			break;
  2430 		case 'restore':
  2619 		case 'restore':
  2431 			$msg = wp_restore_image( $attachment_id );
  2620 			$msg = wp_restore_image( $attachment_id );
  2432 			break;
  2621 			break;
  2433 	}
  2622 	}
  2434 
  2623 
       
  2624 	ob_start();
  2435 	wp_image_editor( $attachment_id, $msg );
  2625 	wp_image_editor( $attachment_id, $msg );
  2436 	wp_die();
  2626 	$html = ob_get_clean();
       
  2627 
       
  2628 	if ( $msg->error ) {
       
  2629 		wp_send_json_error(
       
  2630 			array(
       
  2631 				'message' => $msg,
       
  2632 				'html'    => $html,
       
  2633 			)
       
  2634 		);
       
  2635 	}
       
  2636 
       
  2637 	wp_send_json_success(
       
  2638 		array(
       
  2639 			'message' => $msg,
       
  2640 			'html'    => $html,
       
  2641 		)
       
  2642 	);
  2437 }
  2643 }
  2438 
  2644 
  2439 /**
  2645 /**
  2440  * Ajax handler for setting the featured image.
  2646  * Ajax handler for setting the featured image.
  2441  *
  2647  *
  2442  * @since 3.1.0
  2648  * @since 3.1.0
  2443  */
  2649  */
  2444 function wp_ajax_set_post_thumbnail() {
  2650 function wp_ajax_set_post_thumbnail() {
  2445 	$json = ! empty( $_REQUEST['json'] ); // New-style request
  2651 	$json = ! empty( $_REQUEST['json'] ); // New-style request.
  2446 
  2652 
  2447 	$post_ID = intval( $_POST['post_id'] );
  2653 	$post_ID = intval( $_POST['post_id'] );
  2448 	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  2654 	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  2449 		wp_die( -1 );
  2655 		wp_die( -1 );
  2450 	}
  2656 	}
  2455 		check_ajax_referer( "update-post_$post_ID" );
  2661 		check_ajax_referer( "update-post_$post_ID" );
  2456 	} else {
  2662 	} else {
  2457 		check_ajax_referer( "set_post_thumbnail-$post_ID" );
  2663 		check_ajax_referer( "set_post_thumbnail-$post_ID" );
  2458 	}
  2664 	}
  2459 
  2665 
  2460 	if ( $thumbnail_id == '-1' ) {
  2666 	if ( '-1' == $thumbnail_id ) {
  2461 		if ( delete_post_thumbnail( $post_ID ) ) {
  2667 		if ( delete_post_thumbnail( $post_ID ) ) {
  2462 			$return = _wp_post_thumbnail_html( null, $post_ID );
  2668 			$return = _wp_post_thumbnail_html( null, $post_ID );
  2463 			$json ? wp_send_json_success( $return ) : wp_die( $return );
  2669 			$json ? wp_send_json_success( $return ) : wp_die( $return );
  2464 		} else {
  2670 		} else {
  2465 			wp_die( 0 );
  2671 			wp_die( 0 );
  2597 	} else {
  2803 	} else {
  2598 		$last_date = date_i18n( __( 'F j, Y' ) );
  2804 		$last_date = date_i18n( __( 'F j, Y' ) );
  2599 		$last_time = date_i18n( __( 'g:i a' ) );
  2805 		$last_time = date_i18n( __( 'g:i a' ) );
  2600 	}
  2806 	}
  2601 
  2807 
  2602 	if ( $last_id = get_post_meta( $post_id, '_edit_last', true ) ) {
  2808 	$last_id = get_post_meta( $post_id, '_edit_last', true );
       
  2809 	if ( $last_id ) {
  2603 		$last_user = get_userdata( $last_id );
  2810 		$last_user = get_userdata( $last_id );
  2604 		/* translators: 1: display_name of last user, 2: date of last edit, 3: time of last edit. */
  2811 		/* translators: 1: User's display name, 2: Date of last edit, 3: Time of last edit. */
  2605 		$last_edited = sprintf( __( 'Last edited by %1$s on %2$s at %3$s' ), esc_html( $last_user->display_name ), $last_date, $last_time );
  2812 		$last_edited = sprintf( __( 'Last edited by %1$s on %2$s at %3$s' ), esc_html( $last_user->display_name ), $last_date, $last_time );
  2606 	} else {
  2813 	} else {
  2607 		/* translators: 1: date of last edit, 2: time of last edit. */
  2814 		/* translators: 1: Date of last edit, 2: Time of last edit. */
  2608 		$last_edited = sprintf( __( 'Last edited on %1$s at %2$s' ), $last_date, $last_time );
  2815 		$last_edited = sprintf( __( 'Last edited on %1$s at %2$s' ), $last_date, $last_time );
  2609 	}
  2816 	}
  2610 
  2817 
  2611 	wp_send_json_success( array( 'last_edited' => $last_edited ) );
  2818 	wp_send_json_success( array( 'last_edited' => $last_edited ) );
  2612 }
  2819 }
  2618  */
  2825  */
  2619 function wp_ajax_wp_remove_post_lock() {
  2826 function wp_ajax_wp_remove_post_lock() {
  2620 	if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) ) {
  2827 	if ( empty( $_POST['post_ID'] ) || empty( $_POST['active_post_lock'] ) ) {
  2621 		wp_die( 0 );
  2828 		wp_die( 0 );
  2622 	}
  2829 	}
       
  2830 
  2623 	$post_id = (int) $_POST['post_ID'];
  2831 	$post_id = (int) $_POST['post_ID'];
  2624 	if ( ! $post = get_post( $post_id ) ) {
  2832 	$post    = get_post( $post_id );
       
  2833 
       
  2834 	if ( ! $post ) {
  2625 		wp_die( 0 );
  2835 		wp_die( 0 );
  2626 	}
  2836 	}
  2627 
  2837 
  2628 	check_ajax_referer( 'update-post_' . $post_id );
  2838 	check_ajax_referer( 'update-post_' . $post_id );
  2629 
  2839 
  2630 	if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2840 	if ( ! current_user_can( 'edit_post', $post_id ) ) {
  2631 		wp_die( -1 );
  2841 		wp_die( -1 );
  2632 	}
  2842 	}
  2633 
  2843 
  2634 	$active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
  2844 	$active_lock = array_map( 'absint', explode( ':', $_POST['active_post_lock'] ) );
  2635 	if ( $active_lock[1] != get_current_user_id() ) {
  2845 
       
  2846 	if ( get_current_user_id() != $active_lock[1] ) {
  2636 		wp_die( 0 );
  2847 		wp_die( 0 );
  2637 	}
  2848 	}
  2638 
  2849 
  2639 	/**
  2850 	/**
  2640 	 * Filters the post lock window duration.
  2851 	 * Filters the post lock window duration.
  2654  *
  2865  *
  2655  * @since 3.1.0
  2866  * @since 3.1.0
  2656  */
  2867  */
  2657 function wp_ajax_dismiss_wp_pointer() {
  2868 function wp_ajax_dismiss_wp_pointer() {
  2658 	$pointer = $_POST['pointer'];
  2869 	$pointer = $_POST['pointer'];
  2659 	if ( $pointer != sanitize_key( $pointer ) ) {
  2870 
       
  2871 	if ( sanitize_key( $pointer ) != $pointer ) {
  2660 		wp_die( 0 );
  2872 		wp_die( 0 );
  2661 	}
  2873 	}
  2662 
  2874 
  2663 	//  check_ajax_referer( 'dismiss-pointer_' . $pointer );
  2875 	//  check_ajax_referer( 'dismiss-pointer_' . $pointer );
  2664 
  2876 
  2665 	$dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
  2877 	$dismissed = array_filter( explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) ) );
  2666 
  2878 
  2667 	if ( in_array( $pointer, $dismissed ) ) {
  2879 	if ( in_array( $pointer, $dismissed, true ) ) {
  2668 		wp_die( 0 );
  2880 		wp_die( 0 );
  2669 	}
  2881 	}
  2670 
  2882 
  2671 	$dismissed[] = $pointer;
  2883 	$dismissed[] = $pointer;
  2672 	$dismissed   = implode( ',', $dismissed );
  2884 	$dismissed   = implode( ',', $dismissed );
  2683 function wp_ajax_get_attachment() {
  2895 function wp_ajax_get_attachment() {
  2684 	if ( ! isset( $_REQUEST['id'] ) ) {
  2896 	if ( ! isset( $_REQUEST['id'] ) ) {
  2685 		wp_send_json_error();
  2897 		wp_send_json_error();
  2686 	}
  2898 	}
  2687 
  2899 
  2688 	if ( ! $id = absint( $_REQUEST['id'] ) ) {
  2900 	$id = absint( $_REQUEST['id'] );
       
  2901 	if ( ! $id ) {
  2689 		wp_send_json_error();
  2902 		wp_send_json_error();
  2690 	}
  2903 	}
  2691 
  2904 
  2692 	if ( ! $post = get_post( $id ) ) {
  2905 	$post = get_post( $id );
       
  2906 	if ( ! $post ) {
  2693 		wp_send_json_error();
  2907 		wp_send_json_error();
  2694 	}
  2908 	}
  2695 
  2909 
  2696 	if ( 'attachment' != $post->post_type ) {
  2910 	if ( 'attachment' !== $post->post_type ) {
  2697 		wp_send_json_error();
  2911 		wp_send_json_error();
  2698 	}
  2912 	}
  2699 
  2913 
  2700 	if ( ! current_user_can( 'upload_files' ) ) {
  2914 	if ( ! current_user_can( 'upload_files' ) ) {
  2701 		wp_send_json_error();
  2915 		wp_send_json_error();
  2702 	}
  2916 	}
  2703 
  2917 
  2704 	if ( ! $attachment = wp_prepare_attachment_for_js( $id ) ) {
  2918 	$attachment = wp_prepare_attachment_for_js( $id );
       
  2919 	if ( ! $attachment ) {
  2705 		wp_send_json_error();
  2920 		wp_send_json_error();
  2706 	}
  2921 	}
  2707 
  2922 
  2708 	wp_send_json_success( $attachment );
  2923 	wp_send_json_success( $attachment );
  2709 }
  2924 }
  2731 		'post__in',
  2946 		'post__in',
  2732 		'post__not_in',
  2947 		'post__not_in',
  2733 		'year',
  2948 		'year',
  2734 		'monthnum',
  2949 		'monthnum',
  2735 	);
  2950 	);
       
  2951 
  2736 	foreach ( get_taxonomies_for_attachments( 'objects' ) as $t ) {
  2952 	foreach ( get_taxonomies_for_attachments( 'objects' ) as $t ) {
  2737 		if ( $t->query_var && isset( $query[ $t->query_var ] ) ) {
  2953 		if ( $t->query_var && isset( $query[ $t->query_var ] ) ) {
  2738 			$keys[] = $t->query_var;
  2954 			$keys[] = $t->query_var;
  2739 		}
  2955 		}
  2740 	}
  2956 	}
  2741 
  2957 
  2742 	$query              = array_intersect_key( $query, array_flip( $keys ) );
  2958 	$query              = array_intersect_key( $query, array_flip( $keys ) );
  2743 	$query['post_type'] = 'attachment';
  2959 	$query['post_type'] = 'attachment';
  2744 	if ( MEDIA_TRASH
  2960 
  2745 		&& ! empty( $_REQUEST['query']['post_status'] )
  2961 	if (
  2746 		&& 'trash' === $_REQUEST['query']['post_status'] ) {
  2962 		MEDIA_TRASH &&
       
  2963 		! empty( $_REQUEST['query']['post_status'] ) &&
       
  2964 		'trash' === $_REQUEST['query']['post_status']
       
  2965 	) {
  2747 		$query['post_status'] = 'trash';
  2966 		$query['post_status'] = 'trash';
  2748 	} else {
  2967 	} else {
  2749 		$query['post_status'] = 'inherit';
  2968 		$query['post_status'] = 'inherit';
  2750 	}
  2969 	}
  2751 
  2970 
  2785 function wp_ajax_save_attachment() {
  3004 function wp_ajax_save_attachment() {
  2786 	if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) ) {
  3005 	if ( ! isset( $_REQUEST['id'] ) || ! isset( $_REQUEST['changes'] ) ) {
  2787 		wp_send_json_error();
  3006 		wp_send_json_error();
  2788 	}
  3007 	}
  2789 
  3008 
  2790 	if ( ! $id = absint( $_REQUEST['id'] ) ) {
  3009 	$id = absint( $_REQUEST['id'] );
       
  3010 	if ( ! $id ) {
  2791 		wp_send_json_error();
  3011 		wp_send_json_error();
  2792 	}
  3012 	}
  2793 
  3013 
  2794 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
  3014 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
  2795 
  3015 
  2798 	}
  3018 	}
  2799 
  3019 
  2800 	$changes = $_REQUEST['changes'];
  3020 	$changes = $_REQUEST['changes'];
  2801 	$post    = get_post( $id, ARRAY_A );
  3021 	$post    = get_post( $id, ARRAY_A );
  2802 
  3022 
  2803 	if ( 'attachment' != $post['post_type'] ) {
  3023 	if ( 'attachment' !== $post['post_type'] ) {
  2804 		wp_send_json_error();
  3024 		wp_send_json_error();
  2805 	}
  3025 	}
  2806 
  3026 
  2807 	if ( isset( $changes['parent'] ) ) {
  3027 	if ( isset( $changes['parent'] ) ) {
  2808 		$post['post_parent'] = $changes['parent'];
  3028 		$post['post_parent'] = $changes['parent'];
  2824 		$post['post_status'] = $changes['status'];
  3044 		$post['post_status'] = $changes['status'];
  2825 	}
  3045 	}
  2826 
  3046 
  2827 	if ( isset( $changes['alt'] ) ) {
  3047 	if ( isset( $changes['alt'] ) ) {
  2828 		$alt = wp_unslash( $changes['alt'] );
  3048 		$alt = wp_unslash( $changes['alt'] );
  2829 		if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) {
  3049 		if ( get_post_meta( $id, '_wp_attachment_image_alt', true ) !== $alt ) {
  2830 			$alt = wp_strip_all_tags( $alt, true );
  3050 			$alt = wp_strip_all_tags( $alt, true );
  2831 			update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) );
  3051 			update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) );
  2832 		}
  3052 		}
  2833 	}
  3053 	}
  2834 
  3054 
  2835 	if ( wp_attachment_is( 'audio', $post['ID'] ) ) {
  3055 	if ( wp_attachment_is( 'audio', $post['ID'] ) ) {
  2836 		$changed = false;
  3056 		$changed = false;
  2837 		$id3data = wp_get_attachment_metadata( $post['ID'] );
  3057 		$id3data = wp_get_attachment_metadata( $post['ID'] );
       
  3058 
  2838 		if ( ! is_array( $id3data ) ) {
  3059 		if ( ! is_array( $id3data ) ) {
  2839 			$changed = true;
  3060 			$changed = true;
  2840 			$id3data = array();
  3061 			$id3data = array();
  2841 		}
  3062 		}
       
  3063 
  2842 		foreach ( wp_get_attachment_id3_keys( (object) $post, 'edit' ) as $key => $label ) {
  3064 		foreach ( wp_get_attachment_id3_keys( (object) $post, 'edit' ) as $key => $label ) {
  2843 			if ( isset( $changes[ $key ] ) ) {
  3065 			if ( isset( $changes[ $key ] ) ) {
  2844 				$changed         = true;
  3066 				$changed         = true;
  2845 				$id3data[ $key ] = sanitize_text_field( wp_unslash( $changes[ $key ] ) );
  3067 				$id3data[ $key ] = sanitize_text_field( wp_unslash( $changes[ $key ] ) );
  2846 			}
  3068 			}
  2868 function wp_ajax_save_attachment_compat() {
  3090 function wp_ajax_save_attachment_compat() {
  2869 	if ( ! isset( $_REQUEST['id'] ) ) {
  3091 	if ( ! isset( $_REQUEST['id'] ) ) {
  2870 		wp_send_json_error();
  3092 		wp_send_json_error();
  2871 	}
  3093 	}
  2872 
  3094 
  2873 	if ( ! $id = absint( $_REQUEST['id'] ) ) {
  3095 	$id = absint( $_REQUEST['id'] );
       
  3096 	if ( ! $id ) {
  2874 		wp_send_json_error();
  3097 		wp_send_json_error();
  2875 	}
  3098 	}
  2876 
  3099 
  2877 	if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) ) {
  3100 	if ( empty( $_REQUEST['attachments'] ) || empty( $_REQUEST['attachments'][ $id ] ) ) {
  2878 		wp_send_json_error();
  3101 		wp_send_json_error();
  2879 	}
  3102 	}
       
  3103 
  2880 	$attachment_data = $_REQUEST['attachments'][ $id ];
  3104 	$attachment_data = $_REQUEST['attachments'][ $id ];
  2881 
  3105 
  2882 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
  3106 	check_ajax_referer( 'update-post_' . $id, 'nonce' );
  2883 
  3107 
  2884 	if ( ! current_user_can( 'edit_post', $id ) ) {
  3108 	if ( ! current_user_can( 'edit_post', $id ) ) {
  2885 		wp_send_json_error();
  3109 		wp_send_json_error();
  2886 	}
  3110 	}
  2887 
  3111 
  2888 	$post = get_post( $id, ARRAY_A );
  3112 	$post = get_post( $id, ARRAY_A );
  2889 
  3113 
  2890 	if ( 'attachment' != $post['post_type'] ) {
  3114 	if ( 'attachment' !== $post['post_type'] ) {
  2891 		wp_send_json_error();
  3115 		wp_send_json_error();
  2892 	}
  3116 	}
  2893 
  3117 
  2894 	/** This filter is documented in wp-admin/includes/media.php */
  3118 	/** This filter is documented in wp-admin/includes/media.php */
  2895 	$post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
  3119 	$post = apply_filters( 'attachment_fields_to_save', $post, $attachment_data );
  2905 		if ( isset( $attachment_data[ $taxonomy ] ) ) {
  3129 		if ( isset( $attachment_data[ $taxonomy ] ) ) {
  2906 			wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
  3130 			wp_set_object_terms( $id, array_map( 'trim', preg_split( '/,+/', $attachment_data[ $taxonomy ] ) ), $taxonomy, false );
  2907 		}
  3131 		}
  2908 	}
  3132 	}
  2909 
  3133 
  2910 	if ( ! $attachment = wp_prepare_attachment_for_js( $id ) ) {
  3134 	$attachment = wp_prepare_attachment_for_js( $id );
       
  3135 
       
  3136 	if ( ! $attachment ) {
  2911 		wp_send_json_error();
  3137 		wp_send_json_error();
  2912 	}
  3138 	}
  2913 
  3139 
  2914 	wp_send_json_success( $attachment );
  3140 	wp_send_json_success( $attachment );
  2915 }
  3141 }
  2922 function wp_ajax_save_attachment_order() {
  3148 function wp_ajax_save_attachment_order() {
  2923 	if ( ! isset( $_REQUEST['post_id'] ) ) {
  3149 	if ( ! isset( $_REQUEST['post_id'] ) ) {
  2924 		wp_send_json_error();
  3150 		wp_send_json_error();
  2925 	}
  3151 	}
  2926 
  3152 
  2927 	if ( ! $post_id = absint( $_REQUEST['post_id'] ) ) {
  3153 	$post_id = absint( $_REQUEST['post_id'] );
       
  3154 	if ( ! $post_id ) {
  2928 		wp_send_json_error();
  3155 		wp_send_json_error();
  2929 	}
  3156 	}
  2930 
  3157 
  2931 	if ( empty( $_REQUEST['attachments'] ) ) {
  3158 	if ( empty( $_REQUEST['attachments'] ) ) {
  2932 		wp_send_json_error();
  3159 		wp_send_json_error();
  2942 
  3169 
  2943 	foreach ( $attachments as $attachment_id => $menu_order ) {
  3170 	foreach ( $attachments as $attachment_id => $menu_order ) {
  2944 		if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
  3171 		if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
  2945 			continue;
  3172 			continue;
  2946 		}
  3173 		}
  2947 		if ( ! $attachment = get_post( $attachment_id ) ) {
  3174 
       
  3175 		$attachment = get_post( $attachment_id );
       
  3176 
       
  3177 		if ( ! $attachment ) {
  2948 			continue;
  3178 			continue;
  2949 		}
  3179 		}
  2950 		if ( 'attachment' != $attachment->post_type ) {
  3180 
       
  3181 		if ( 'attachment' !== $attachment->post_type ) {
  2951 			continue;
  3182 			continue;
  2952 		}
  3183 		}
  2953 
  3184 
  2954 		wp_update_post(
  3185 		wp_update_post(
  2955 			array(
  3186 			array(
  2976 
  3207 
  2977 	$attachment = wp_unslash( $_POST['attachment'] );
  3208 	$attachment = wp_unslash( $_POST['attachment'] );
  2978 
  3209 
  2979 	$id = intval( $attachment['id'] );
  3210 	$id = intval( $attachment['id'] );
  2980 
  3211 
  2981 	if ( ! $post = get_post( $id ) ) {
  3212 	$post = get_post( $id );
       
  3213 	if ( ! $post ) {
  2982 		wp_send_json_error();
  3214 		wp_send_json_error();
  2983 	}
  3215 	}
  2984 
  3216 
  2985 	if ( 'attachment' != $post->post_type ) {
  3217 	if ( 'attachment' !== $post->post_type ) {
  2986 		wp_send_json_error();
  3218 		wp_send_json_error();
  2987 	}
  3219 	}
  2988 
  3220 
  2989 	if ( current_user_can( 'edit_post', $id ) ) {
  3221 	if ( current_user_can( 'edit_post', $id ) ) {
  2990 		// If this attachment is unattached, attach it. Primarily a back compat thing.
  3222 		// If this attachment is unattached, attach it. Primarily a back compat thing.
  2991 		if ( 0 == $post->post_parent && $insert_into_post_id = intval( $_POST['post_id'] ) ) {
  3223 		$insert_into_post_id = intval( $_POST['post_id'] );
       
  3224 
       
  3225 		if ( 0 == $post->post_parent && $insert_into_post_id ) {
  2992 			wp_update_post(
  3226 			wp_update_post(
  2993 				array(
  3227 				array(
  2994 					'ID'          => $id,
  3228 					'ID'          => $id,
  2995 					'post_parent' => $insert_into_post_id,
  3229 					'post_parent' => $insert_into_post_id,
  2996 				)
  3230 				)
  3018 		$html  = get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt );
  3252 		$html  = get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt );
  3019 	} elseif ( wp_attachment_is( 'video', $post ) || wp_attachment_is( 'audio', $post ) ) {
  3253 	} elseif ( wp_attachment_is( 'video', $post ) || wp_attachment_is( 'audio', $post ) ) {
  3020 		$html = stripslashes_deep( $_POST['html'] );
  3254 		$html = stripslashes_deep( $_POST['html'] );
  3021 	} else {
  3255 	} else {
  3022 		$html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
  3256 		$html = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
  3023 		$rel  = $rel ? ' rel="attachment wp-att-' . $id . '"' : ''; // Hard-coded string, $id is already sanitized
  3257 		$rel  = $rel ? ' rel="attachment wp-att-' . $id . '"' : ''; // Hard-coded string, $id is already sanitized.
  3024 
  3258 
  3025 		if ( ! empty( $url ) ) {
  3259 		if ( ! empty( $url ) ) {
  3026 			$html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
  3260 			$html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
  3027 		}
  3261 		}
  3028 	}
  3262 	}
  3043  * - audio_send_to_editor_url
  3277  * - audio_send_to_editor_url
  3044  * - video_send_to_editor_url
  3278  * - video_send_to_editor_url
  3045  *
  3279  *
  3046  * @since 3.5.0
  3280  * @since 3.5.0
  3047  *
  3281  *
  3048  * @global WP_Post  $post
  3282  * @global WP_Post  $post     Global post object.
  3049  * @global WP_Embed $wp_embed
  3283  * @global WP_Embed $wp_embed
  3050  */
  3284  */
  3051 function wp_ajax_send_link_to_editor() {
  3285 function wp_ajax_send_link_to_editor() {
  3052 	global $post, $wp_embed;
  3286 	global $post, $wp_embed;
  3053 
  3287 
  3054 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
  3288 	check_ajax_referer( 'media-send-to-editor', 'nonce' );
  3055 
  3289 
  3056 	if ( ! $src = wp_unslash( $_POST['src'] ) ) {
  3290 	$src = wp_unslash( $_POST['src'] );
       
  3291 	if ( ! $src ) {
  3057 		wp_send_json_error();
  3292 		wp_send_json_error();
  3058 	}
  3293 	}
  3059 
  3294 
  3060 	if ( ! strpos( $src, '://' ) ) {
  3295 	if ( ! strpos( $src, '://' ) ) {
  3061 		$src = 'http://' . $src;
  3296 		$src = 'http://' . $src;
  3062 	}
  3297 	}
  3063 
  3298 
  3064 	if ( ! $src = esc_url_raw( $src ) ) {
  3299 	$src = esc_url_raw( $src );
       
  3300 	if ( ! $src ) {
  3065 		wp_send_json_error();
  3301 		wp_send_json_error();
  3066 	}
  3302 	}
  3067 
  3303 
  3068 	if ( ! $link_text = trim( wp_unslash( $_POST['link_text'] ) ) ) {
  3304 	$link_text = trim( wp_unslash( $_POST['link_text'] ) );
       
  3305 	if ( ! $link_text ) {
  3069 		$link_text = wp_basename( $src );
  3306 		$link_text = wp_basename( $src );
  3070 	}
  3307 	}
  3071 
  3308 
  3072 	$post = get_post( isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0 );
  3309 	$post = get_post( isset( $_POST['post_id'] ) ? $_POST['post_id'] : 0 );
  3073 
  3310 
  3076 
  3313 
  3077 	// Fallback that WordPress creates when no oEmbed was found.
  3314 	// Fallback that WordPress creates when no oEmbed was found.
  3078 	$fallback = $wp_embed->maybe_make_link( $src );
  3315 	$fallback = $wp_embed->maybe_make_link( $src );
  3079 
  3316 
  3080 	if ( $check_embed !== $fallback ) {
  3317 	if ( $check_embed !== $fallback ) {
  3081 		// TinyMCE view for [embed] will parse this
  3318 		// TinyMCE view for [embed] will parse this.
  3082 		$html = '[embed]' . $src . '[/embed]';
  3319 		$html = '[embed]' . $src . '[/embed]';
  3083 	} elseif ( $link_text ) {
  3320 	} elseif ( $link_text ) {
  3084 		$html = '<a href="' . esc_url( $src ) . '">' . $link_text . '</a>';
  3321 		$html = '<a href="' . esc_url( $src ) . '">' . $link_text . '</a>';
  3085 	} else {
  3322 	} else {
  3086 		$html = '';
  3323 		$html = '';
  3087 	}
  3324 	}
  3088 
  3325 
  3089 	// Figure out what filter to run:
  3326 	// Figure out what filter to run:
  3090 	$type = 'file';
  3327 	$type = 'file';
  3091 	if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) )
  3328 	$ext  = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src );
  3092 		&& ( 'audio' == $ext_type || 'video' == $ext_type ) ) {
  3329 	if ( $ext ) {
       
  3330 		$ext_type = wp_ext2type( $ext );
       
  3331 		if ( 'audio' === $ext_type || 'video' === $ext_type ) {
  3093 			$type = $ext_type;
  3332 			$type = $ext_type;
       
  3333 		}
  3094 	}
  3334 	}
  3095 
  3335 
  3096 	/** This filter is documented in wp-admin/includes/media.php */
  3336 	/** This filter is documented in wp-admin/includes/media.php */
  3097 	$html = apply_filters( "{$type}_send_to_editor_url", $html, $src, $link_text );
  3337 	$html = apply_filters( "{$type}_send_to_editor_url", $html, $src, $link_text );
  3098 
  3338 
  3109 function wp_ajax_heartbeat() {
  3349 function wp_ajax_heartbeat() {
  3110 	if ( empty( $_POST['_nonce'] ) ) {
  3350 	if ( empty( $_POST['_nonce'] ) ) {
  3111 		wp_send_json_error();
  3351 		wp_send_json_error();
  3112 	}
  3352 	}
  3113 
  3353 
  3114 	$response    = $data = array();
  3354 	$response    = array();
       
  3355 	$data        = array();
  3115 	$nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' );
  3356 	$nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' );
  3116 
  3357 
  3117 	// screen_id is the same as $current_screen->id and the JS global 'pagenow'.
  3358 	// 'screen_id' is the same as $current_screen->id and the JS global 'pagenow'.
  3118 	if ( ! empty( $_POST['screen_id'] ) ) {
  3359 	if ( ! empty( $_POST['screen_id'] ) ) {
  3119 		$screen_id = sanitize_key( $_POST['screen_id'] );
  3360 		$screen_id = sanitize_key( $_POST['screen_id'] );
  3120 	} else {
  3361 	} else {
  3121 		$screen_id = 'front';
  3362 		$screen_id = 'front';
  3122 	}
  3363 	}
  3131 		 *
  3372 		 *
  3132 		 * @since 4.3.0
  3373 		 * @since 4.3.0
  3133 		 *
  3374 		 *
  3134 		 * @param array  $response  The Heartbeat response.
  3375 		 * @param array  $response  The Heartbeat response.
  3135 		 * @param array  $data      The $_POST data sent.
  3376 		 * @param array  $data      The $_POST data sent.
  3136 		 * @param string $screen_id The screen id.
  3377 		 * @param string $screen_id The screen ID.
  3137 		 */
  3378 		 */
  3138 		$response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id );
  3379 		$response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id );
  3139 
  3380 
  3140 		if ( false === $nonce_state ) {
  3381 		if ( false === $nonce_state ) {
  3141 			// User is logged in but nonces have expired.
  3382 			// User is logged in but nonces have expired.
  3150 		 *
  3391 		 *
  3151 		 * @since 3.6.0
  3392 		 * @since 3.6.0
  3152 		 *
  3393 		 *
  3153 		 * @param array  $response  The Heartbeat response.
  3394 		 * @param array  $response  The Heartbeat response.
  3154 		 * @param array  $data      The $_POST data sent.
  3395 		 * @param array  $data      The $_POST data sent.
  3155 		 * @param string $screen_id The screen id.
  3396 		 * @param string $screen_id The screen ID.
  3156 		 */
  3397 		 */
  3157 		$response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
  3398 		$response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
  3158 	}
  3399 	}
  3159 
  3400 
  3160 	/**
  3401 	/**
  3161 	 * Filters the Heartbeat response sent.
  3402 	 * Filters the Heartbeat response sent.
  3162 	 *
  3403 	 *
  3163 	 * @since 3.6.0
  3404 	 * @since 3.6.0
  3164 	 *
  3405 	 *
  3165 	 * @param array  $response  The Heartbeat response.
  3406 	 * @param array  $response  The Heartbeat response.
  3166 	 * @param string $screen_id The screen id.
  3407 	 * @param string $screen_id The screen ID.
  3167 	 */
  3408 	 */
  3168 	$response = apply_filters( 'heartbeat_send', $response, $screen_id );
  3409 	$response = apply_filters( 'heartbeat_send', $response, $screen_id );
  3169 
  3410 
  3170 	/**
  3411 	/**
  3171 	 * Fires when Heartbeat ticks in logged-in environments.
  3412 	 * Fires when Heartbeat ticks in logged-in environments.
  3173 	 * Allows the transport to be easily replaced with long-polling.
  3414 	 * Allows the transport to be easily replaced with long-polling.
  3174 	 *
  3415 	 *
  3175 	 * @since 3.6.0
  3416 	 * @since 3.6.0
  3176 	 *
  3417 	 *
  3177 	 * @param array  $response  The Heartbeat response.
  3418 	 * @param array  $response  The Heartbeat response.
  3178 	 * @param string $screen_id The screen id.
  3419 	 * @param string $screen_id The screen ID.
  3179 	 */
  3420 	 */
  3180 	do_action( 'heartbeat_tick', $response, $screen_id );
  3421 	do_action( 'heartbeat_tick', $response, $screen_id );
  3181 
  3422 
  3182 	// Send the current time according to the server
  3423 	// Send the current time according to the server.
  3183 	$response['server_time'] = time();
  3424 	$response['server_time'] = time();
  3184 
  3425 
  3185 	wp_send_json( $response );
  3426 	wp_send_json( $response );
  3186 }
  3427 }
  3187 
  3428 
  3191  * @since 3.6.0
  3432  * @since 3.6.0
  3192  */
  3433  */
  3193 function wp_ajax_get_revision_diffs() {
  3434 function wp_ajax_get_revision_diffs() {
  3194 	require ABSPATH . 'wp-admin/includes/revision.php';
  3435 	require ABSPATH . 'wp-admin/includes/revision.php';
  3195 
  3436 
  3196 	if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) ) {
  3437 	$post = get_post( (int) $_REQUEST['post_id'] );
       
  3438 	if ( ! $post ) {
  3197 		wp_send_json_error();
  3439 		wp_send_json_error();
  3198 	}
  3440 	}
  3199 
  3441 
  3200 	if ( ! current_user_can( 'edit_post', $post->ID ) ) {
  3442 	if ( ! current_user_can( 'edit_post', $post->ID ) ) {
  3201 		wp_send_json_error();
  3443 		wp_send_json_error();
  3202 	}
  3444 	}
  3203 
  3445 
  3204 	// Really just pre-loading the cache here.
  3446 	// Really just pre-loading the cache here.
  3205 	if ( ! $revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) ) ) {
  3447 	$revisions = wp_get_post_revisions( $post->ID, array( 'check_enabled' => false ) );
       
  3448 	if ( ! $revisions ) {
  3206 		wp_send_json_error();
  3449 		wp_send_json_error();
  3207 	}
  3450 	}
  3208 
  3451 
  3209 	$return = array();
  3452 	$return = array();
  3210 	@set_time_limit( 0 );
  3453 	set_time_limit( 0 );
  3211 
  3454 
  3212 	foreach ( $_REQUEST['compare'] as $compare_key ) {
  3455 	foreach ( $_REQUEST['compare'] as $compare_key ) {
  3213 		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
  3456 		list( $compare_from, $compare_to ) = explode( ':', $compare_key ); // from:to
  3214 
  3457 
  3215 		$return[] = array(
  3458 		$return[] = array(
  3295 	if ( is_wp_error( $api ) ) {
  3538 	if ( is_wp_error( $api ) ) {
  3296 		wp_send_json_error();
  3539 		wp_send_json_error();
  3297 	}
  3540 	}
  3298 
  3541 
  3299 	$update_php = network_admin_url( 'update.php?action=install-theme' );
  3542 	$update_php = network_admin_url( 'update.php?action=install-theme' );
       
  3543 
  3300 	foreach ( $api->themes as &$theme ) {
  3544 	foreach ( $api->themes as &$theme ) {
  3301 		$theme->install_url = add_query_arg(
  3545 		$theme->install_url = add_query_arg(
  3302 			array(
  3546 			array(
  3303 				'theme'    => $theme->slug,
  3547 				'theme'    => $theme->slug,
  3304 				'_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
  3548 				'_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
  3339 
  3583 
  3340 		$theme->name        = wp_kses( $theme->name, $themes_allowedtags );
  3584 		$theme->name        = wp_kses( $theme->name, $themes_allowedtags );
  3341 		$theme->author      = wp_kses( $theme->author['display_name'], $themes_allowedtags );
  3585 		$theme->author      = wp_kses( $theme->author['display_name'], $themes_allowedtags );
  3342 		$theme->version     = wp_kses( $theme->version, $themes_allowedtags );
  3586 		$theme->version     = wp_kses( $theme->version, $themes_allowedtags );
  3343 		$theme->description = wp_kses( $theme->description, $themes_allowedtags );
  3587 		$theme->description = wp_kses( $theme->description, $themes_allowedtags );
  3344 		$theme->stars       = wp_star_rating(
  3588 
       
  3589 		$theme->stars = wp_star_rating(
  3345 			array(
  3590 			array(
  3346 				'rating' => $theme->rating,
  3591 				'rating' => $theme->rating,
  3347 				'type'   => 'percent',
  3592 				'type'   => 'percent',
  3348 				'number' => $theme->num_ratings,
  3593 				'number' => $theme->num_ratings,
  3349 				'echo'   => false,
  3594 				'echo'   => false,
  3350 			)
  3595 			)
  3351 		);
  3596 		);
  3352 		$theme->num_ratings = number_format_i18n( $theme->num_ratings );
  3597 
  3353 		$theme->preview_url = set_url_scheme( $theme->preview_url );
  3598 		$theme->num_ratings    = number_format_i18n( $theme->num_ratings );
       
  3599 		$theme->preview_url    = set_url_scheme( $theme->preview_url );
       
  3600 		$theme->compatible_wp  = is_wp_version_compatible( $theme->requires );
       
  3601 		$theme->compatible_php = is_php_version_compatible( $theme->requires_php );
  3354 	}
  3602 	}
  3355 
  3603 
  3356 	wp_send_json_success( $api );
  3604 	wp_send_json_success( $api );
  3357 }
  3605 }
  3358 
  3606 
  3359 /**
  3607 /**
  3360  * Apply [embed] Ajax handlers to a string.
  3608  * Apply [embed] Ajax handlers to a string.
  3361  *
  3609  *
  3362  * @since 4.0.0
  3610  * @since 4.0.0
  3363  *
  3611  *
  3364  * @global WP_Post    $post       Global $post.
  3612  * @global WP_Post    $post       Global post object.
  3365  * @global WP_Embed   $wp_embed   Embed API instance.
  3613  * @global WP_Embed   $wp_embed   Embed API instance.
  3366  * @global WP_Scripts $wp_scripts
  3614  * @global WP_Scripts $wp_scripts
  3367  * @global int        $content_width
  3615  * @global int        $content_width
  3368  */
  3616  */
  3369 function wp_ajax_parse_embed() {
  3617 function wp_ajax_parse_embed() {
  3370 	global $post, $wp_embed, $content_width;
  3618 	global $post, $wp_embed, $content_width;
  3371 
  3619 
  3372 	if ( empty( $_POST['shortcode'] ) ) {
  3620 	if ( empty( $_POST['shortcode'] ) ) {
  3373 		wp_send_json_error();
  3621 		wp_send_json_error();
  3374 	}
  3622 	}
       
  3623 
  3375 	$post_id = isset( $_POST['post_ID'] ) ? intval( $_POST['post_ID'] ) : 0;
  3624 	$post_id = isset( $_POST['post_ID'] ) ? intval( $_POST['post_ID'] ) : 0;
       
  3625 
  3376 	if ( $post_id > 0 ) {
  3626 	if ( $post_id > 0 ) {
  3377 		$post = get_post( $post_id );
  3627 		$post = get_post( $post_id );
       
  3628 
  3378 		if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3629 		if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3379 			wp_send_json_error();
  3630 			wp_send_json_error();
  3380 		}
  3631 		}
  3381 		setup_postdata( $post );
  3632 		setup_postdata( $post );
  3382 	} elseif ( ! current_user_can( 'edit_posts' ) ) { // See WP_oEmbed_Controller::get_proxy_item_permissions_check().
  3633 	} elseif ( ! current_user_can( 'edit_posts' ) ) { // See WP_oEmbed_Controller::get_proxy_item_permissions_check().
  3385 
  3636 
  3386 	$shortcode = wp_unslash( $_POST['shortcode'] );
  3637 	$shortcode = wp_unslash( $_POST['shortcode'] );
  3387 
  3638 
  3388 	preg_match( '/' . get_shortcode_regex() . '/s', $shortcode, $matches );
  3639 	preg_match( '/' . get_shortcode_regex() . '/s', $shortcode, $matches );
  3389 	$atts = shortcode_parse_atts( $matches[3] );
  3640 	$atts = shortcode_parse_atts( $matches[3] );
       
  3641 
  3390 	if ( ! empty( $matches[5] ) ) {
  3642 	if ( ! empty( $matches[5] ) ) {
  3391 		$url = $matches[5];
  3643 		$url = $matches[5];
  3392 	} elseif ( ! empty( $atts['src'] ) ) {
  3644 	} elseif ( ! empty( $atts['src'] ) ) {
  3393 		$url = $atts['src'];
  3645 		$url = $atts['src'];
  3394 	} else {
  3646 	} else {
  3433 
  3685 
  3434 	if ( ! $parsed ) {
  3686 	if ( ! $parsed ) {
  3435 		wp_send_json_error(
  3687 		wp_send_json_error(
  3436 			array(
  3688 			array(
  3437 				'type'    => 'not-embeddable',
  3689 				'type'    => 'not-embeddable',
  3438 				/* translators: %s: URL which cannot be embedded, between code tags */
  3690 				/* translators: %s: URL that could not be embedded. */
  3439 				'message' => sprintf( __( '%s failed to embed.' ), '<code>' . esc_html( $url ) . '</code>' ),
  3691 				'message' => sprintf( __( '%s failed to embed.' ), '<code>' . esc_html( $url ) . '</code>' ),
  3440 			)
  3692 			)
  3441 		);
  3693 		);
  3442 	}
  3694 	}
  3443 
  3695 
  3444 	if ( has_shortcode( $parsed, 'audio' ) || has_shortcode( $parsed, 'video' ) ) {
  3696 	if ( has_shortcode( $parsed, 'audio' ) || has_shortcode( $parsed, 'video' ) ) {
  3445 		$styles     = '';
  3697 		$styles     = '';
  3446 		$mce_styles = wpview_media_sandbox_styles();
  3698 		$mce_styles = wpview_media_sandbox_styles();
       
  3699 
  3447 		foreach ( $mce_styles as $style ) {
  3700 		foreach ( $mce_styles as $style ) {
  3448 			$styles .= sprintf( '<link rel="stylesheet" href="%s"/>', $style );
  3701 			$styles .= sprintf( '<link rel="stylesheet" href="%s"/>', $style );
  3449 		}
  3702 		}
  3450 
  3703 
  3451 		$html = do_shortcode( $parsed );
  3704 		$html = do_shortcode( $parsed );
  3452 
  3705 
  3453 		global $wp_scripts;
  3706 		global $wp_scripts;
       
  3707 
  3454 		if ( ! empty( $wp_scripts ) ) {
  3708 		if ( ! empty( $wp_scripts ) ) {
  3455 			$wp_scripts->done = array();
  3709 			$wp_scripts->done = array();
  3456 		}
  3710 		}
       
  3711 
  3457 		ob_start();
  3712 		ob_start();
  3458 		wp_print_scripts( array( 'mediaelement-vimeo', 'wp-mediaelement' ) );
  3713 		wp_print_scripts( array( 'mediaelement-vimeo', 'wp-mediaelement' ) );
  3459 		$scripts = ob_get_clean();
  3714 		$scripts = ob_get_clean();
  3460 
  3715 
  3461 		$parsed = $styles . $html . $scripts;
  3716 		$parsed = $styles . $html . $scripts;
  3492 }
  3747 }
  3493 
  3748 
  3494 /**
  3749 /**
  3495  * @since 4.0.0
  3750  * @since 4.0.0
  3496  *
  3751  *
  3497  * @global WP_Post    $post
  3752  * @global WP_Post    $post       Global post object.
  3498  * @global WP_Scripts $wp_scripts
  3753  * @global WP_Scripts $wp_scripts
  3499  */
  3754  */
  3500 function wp_ajax_parse_media_shortcode() {
  3755 function wp_ajax_parse_media_shortcode() {
  3501 	global $post, $wp_scripts;
  3756 	global $post, $wp_scripts;
  3502 
  3757 
  3508 
  3763 
  3509 	if ( ! empty( $_POST['post_ID'] ) ) {
  3764 	if ( ! empty( $_POST['post_ID'] ) ) {
  3510 		$post = get_post( (int) $_POST['post_ID'] );
  3765 		$post = get_post( (int) $_POST['post_ID'] );
  3511 	}
  3766 	}
  3512 
  3767 
  3513 	// the embed shortcode requires a post
  3768 	// The embed shortcode requires a post.
  3514 	if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3769 	if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
  3515 		if ( 'embed' === $shortcode ) {
  3770 		if ( 'embed' === $shortcode ) {
  3516 			wp_send_json_error();
  3771 			wp_send_json_error();
  3517 		}
  3772 		}
  3518 	} else {
  3773 	} else {
  3566  *
  3821  *
  3567  * @since 4.1.0
  3822  * @since 4.1.0
  3568  */
  3823  */
  3569 function wp_ajax_destroy_sessions() {
  3824 function wp_ajax_destroy_sessions() {
  3570 	$user = get_userdata( (int) $_POST['user_id'] );
  3825 	$user = get_userdata( (int) $_POST['user_id'] );
       
  3826 
  3571 	if ( $user ) {
  3827 	if ( $user ) {
  3572 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  3828 		if ( ! current_user_can( 'edit_user', $user->ID ) ) {
  3573 			$user = false;
  3829 			$user = false;
  3574 		} elseif ( ! wp_verify_nonce( $_POST['nonce'], 'update-user_' . $user->ID ) ) {
  3830 		} elseif ( ! wp_verify_nonce( $_POST['nonce'], 'update-user_' . $user->ID ) ) {
  3575 			$user = false;
  3831 			$user = false;
  3584 		);
  3840 		);
  3585 	}
  3841 	}
  3586 
  3842 
  3587 	$sessions = WP_Session_Tokens::get_instance( $user->ID );
  3843 	$sessions = WP_Session_Tokens::get_instance( $user->ID );
  3588 
  3844 
  3589 	if ( $user->ID === get_current_user_id() ) {
  3845 	if ( get_current_user_id() === $user->ID ) {
  3590 		$sessions->destroy_others( wp_get_session_token() );
  3846 		$sessions->destroy_others( wp_get_session_token() );
  3591 		$message = __( 'You are now logged out everywhere else.' );
  3847 		$message = __( 'You are now logged out everywhere else.' );
  3592 	} else {
  3848 	} else {
  3593 		$sessions->destroy_all();
  3849 		$sessions->destroy_all();
  3594 		/* translators: %s: User's display name. */
  3850 		/* translators: %s: User's display name. */
  3605  */
  3861  */
  3606 function wp_ajax_crop_image() {
  3862 function wp_ajax_crop_image() {
  3607 	$attachment_id = absint( $_POST['id'] );
  3863 	$attachment_id = absint( $_POST['id'] );
  3608 
  3864 
  3609 	check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' );
  3865 	check_ajax_referer( 'image_editor-' . $attachment_id, 'nonce' );
       
  3866 
  3610 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  3867 	if ( empty( $attachment_id ) || ! current_user_can( 'edit_post', $attachment_id ) ) {
  3611 		wp_send_json_error();
  3868 		wp_send_json_error();
  3612 	}
  3869 	}
  3613 
  3870 
  3614 	$context = str_replace( '_', '-', $_POST['context'] );
  3871 	$context = str_replace( '_', '-', $_POST['context'] );
  3633 				// Additional sizes in wp_prepare_attachment_for_js().
  3890 				// Additional sizes in wp_prepare_attachment_for_js().
  3634 				add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
  3891 				add_filter( 'image_size_names_choose', array( $wp_site_icon, 'additional_sizes' ) );
  3635 				break;
  3892 				break;
  3636 			}
  3893 			}
  3637 
  3894 
  3638 			/** This filter is documented in wp-admin/custom-header.php */
  3895 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  3639 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3896 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3640 			$object  = $wp_site_icon->create_attachment_object( $cropped, $attachment_id );
  3897 			$object  = $wp_site_icon->create_attachment_object( $cropped, $attachment_id );
  3641 			unset( $object['ID'] );
  3898 			unset( $object['ID'] );
  3642 
  3899 
  3643 			// Update the attachment.
  3900 			// Update the attachment.
  3661 			 * @param int    $attachment_id The attachment ID of the original image.
  3918 			 * @param int    $attachment_id The attachment ID of the original image.
  3662 			 * @param string $cropped       Path to the cropped image file.
  3919 			 * @param string $cropped       Path to the cropped image file.
  3663 			 */
  3920 			 */
  3664 			do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
  3921 			do_action( 'wp_ajax_crop_image_pre_save', $context, $attachment_id, $cropped );
  3665 
  3922 
  3666 			/** This filter is documented in wp-admin/custom-header.php */
  3923 			/** This filter is documented in wp-admin/includes/class-custom-image-header.php */
  3667 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3924 			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
  3668 
  3925 
  3669 			$parent_url = wp_get_attachment_url( $attachment_id );
  3926 			$parent_url = wp_get_attachment_url( $attachment_id );
  3670 			$url        = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url );
  3927 			$url        = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url );
  3671 
  3928 
  3771 	if ( ! current_user_can( 'install_themes' ) ) {
  4028 	if ( ! current_user_can( 'install_themes' ) ) {
  3772 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' );
  4029 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install themes on this site.' );
  3773 		wp_send_json_error( $status );
  4030 		wp_send_json_error( $status );
  3774 	}
  4031 	}
  3775 
  4032 
  3776 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
  4033 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  3777 	include_once( ABSPATH . 'wp-admin/includes/theme.php' );
  4034 	include_once ABSPATH . 'wp-admin/includes/theme.php';
  3778 
  4035 
  3779 	$api = themes_api(
  4036 	$api = themes_api(
  3780 		'theme_information',
  4037 		'theme_information',
  3781 		array(
  4038 		array(
  3782 			'slug'   => $slug,
  4039 			'slug'   => $slug,
  3900 	$theme = wp_get_theme( $stylesheet );
  4157 	$theme = wp_get_theme( $stylesheet );
  3901 	if ( $theme->exists() ) {
  4158 	if ( $theme->exists() ) {
  3902 		$status['oldVersion'] = $theme->get( 'Version' );
  4159 		$status['oldVersion'] = $theme->get( 'Version' );
  3903 	}
  4160 	}
  3904 
  4161 
  3905 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
  4162 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  3906 
  4163 
  3907 	$current = get_site_transient( 'update_themes' );
  4164 	$current = get_site_transient( 'update_themes' );
  3908 	if ( empty( $current ) ) {
  4165 	if ( empty( $current ) ) {
  3909 		wp_update_themes();
  4166 		wp_update_themes();
  3910 	}
  4167 	}
  3951 
  4208 
  3952 		wp_send_json_error( $status );
  4209 		wp_send_json_error( $status );
  3953 	}
  4210 	}
  3954 
  4211 
  3955 	// An unhandled error occurred.
  4212 	// An unhandled error occurred.
  3956 	$status['errorMessage'] = __( 'Update failed.' );
  4213 	$status['errorMessage'] = __( 'Theme update failed.' );
  3957 	wp_send_json_error( $status );
  4214 	wp_send_json_error( $status );
  3958 }
  4215 }
  3959 
  4216 
  3960 /**
  4217 /**
  3961  * Ajax handler for deleting a theme.
  4218  * Ajax handler for deleting a theme.
  3995 		wp_send_json_error( $status );
  4252 		wp_send_json_error( $status );
  3996 	}
  4253 	}
  3997 
  4254 
  3998 	// Check filesystem credentials. `delete_theme()` will bail otherwise.
  4255 	// Check filesystem credentials. `delete_theme()` will bail otherwise.
  3999 	$url = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet );
  4256 	$url = wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet );
       
  4257 
  4000 	ob_start();
  4258 	ob_start();
  4001 	$credentials = request_filesystem_credentials( $url );
  4259 	$credentials = request_filesystem_credentials( $url );
  4002 	ob_end_clean();
  4260 	ob_end_clean();
       
  4261 
  4003 	if ( false === $credentials || ! WP_Filesystem( $credentials ) ) {
  4262 	if ( false === $credentials || ! WP_Filesystem( $credentials ) ) {
  4004 		global $wp_filesystem;
  4263 		global $wp_filesystem;
  4005 
  4264 
  4006 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4265 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4007 		$status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
  4266 		$status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
  4012 		}
  4271 		}
  4013 
  4272 
  4014 		wp_send_json_error( $status );
  4273 		wp_send_json_error( $status );
  4015 	}
  4274 	}
  4016 
  4275 
  4017 	include_once( ABSPATH . 'wp-admin/includes/theme.php' );
  4276 	include_once ABSPATH . 'wp-admin/includes/theme.php';
  4018 
  4277 
  4019 	$result = delete_theme( $stylesheet );
  4278 	$result = delete_theme( $stylesheet );
  4020 
  4279 
  4021 	if ( is_wp_error( $result ) ) {
  4280 	if ( is_wp_error( $result ) ) {
  4022 		$status['errorMessage'] = $result->get_error_message();
  4281 		$status['errorMessage'] = $result->get_error_message();
  4059 	if ( ! current_user_can( 'install_plugins' ) ) {
  4318 	if ( ! current_user_can( 'install_plugins' ) ) {
  4060 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' );
  4319 		$status['errorMessage'] = __( 'Sorry, you are not allowed to install plugins on this site.' );
  4061 		wp_send_json_error( $status );
  4320 		wp_send_json_error( $status );
  4062 	}
  4321 	}
  4063 
  4322 
  4064 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
  4323 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4065 	include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
  4324 	include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
  4066 
  4325 
  4067 	$api = plugins_api(
  4326 	$api = plugins_api(
  4068 		'plugin_information',
  4327 		'plugin_information',
  4069 		array(
  4328 		array(
  4070 			'slug'   => sanitize_key( wp_unslash( $_POST['slug'] ) ),
  4329 			'slug'   => sanitize_key( wp_unslash( $_POST['slug'] ) ),
  4177 	$plugin_data          = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
  4436 	$plugin_data          = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
  4178 	$status['plugin']     = $plugin;
  4437 	$status['plugin']     = $plugin;
  4179 	$status['pluginName'] = $plugin_data['Name'];
  4438 	$status['pluginName'] = $plugin_data['Name'];
  4180 
  4439 
  4181 	if ( $plugin_data['Version'] ) {
  4440 	if ( $plugin_data['Version'] ) {
  4182 		/* translators: %s: Plugin version */
  4441 		/* translators: %s: Plugin version. */
  4183 		$status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
  4442 		$status['oldVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
  4184 	}
  4443 	}
  4185 
  4444 
  4186 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
  4445 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
  4187 
  4446 
  4188 	wp_update_plugins();
  4447 	wp_update_plugins();
  4189 
  4448 
  4190 	$skin     = new WP_Ajax_Upgrader_Skin();
  4449 	$skin     = new WP_Ajax_Upgrader_Skin();
  4191 	$upgrader = new Plugin_Upgrader( $skin );
  4450 	$upgrader = new Plugin_Upgrader( $skin );
  4201 		wp_send_json_error( $status );
  4460 		wp_send_json_error( $status );
  4202 	} elseif ( $skin->get_errors()->has_errors() ) {
  4461 	} elseif ( $skin->get_errors()->has_errors() ) {
  4203 		$status['errorMessage'] = $skin->get_error_messages();
  4462 		$status['errorMessage'] = $skin->get_error_messages();
  4204 		wp_send_json_error( $status );
  4463 		wp_send_json_error( $status );
  4205 	} elseif ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) {
  4464 	} elseif ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) {
  4206 		$plugin_update_data = current( $result );
       
  4207 
  4465 
  4208 		/*
  4466 		/*
  4209 		 * If the `update_plugins` site transient is empty (e.g. when you update
  4467 		 * Plugin is already at the latest version.
  4210 		 * two plugins in quick succession before the transient repopulates),
  4468 		 *
  4211 		 * this may be the return.
  4469 		 * This may also be the return value if the `update_plugins` site transient is empty,
       
  4470 		 * e.g. when you update two plugins in quick succession before the transient repopulates.
  4212 		 *
  4471 		 *
  4213 		 * Preferably something can be done to ensure `update_plugins` isn't empty.
  4472 		 * Preferably something can be done to ensure `update_plugins` isn't empty.
  4214 		 * For now, surface some sort of error here.
  4473 		 * For now, surface some sort of error here.
  4215 		 */
  4474 		 */
  4216 		if ( true === $plugin_update_data ) {
  4475 		if ( true === $result[ $plugin ] ) {
  4217 			$status['errorMessage'] = __( 'Plugin update failed.' );
  4476 			$status['errorMessage'] = $upgrader->strings['up_to_date'];
  4218 			wp_send_json_error( $status );
  4477 			wp_send_json_error( $status );
  4219 		}
  4478 		}
  4220 
  4479 
  4221 		$plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] );
  4480 		$plugin_data = get_plugins( '/' . $result[ $plugin ]['destination_name'] );
  4222 		$plugin_data = reset( $plugin_data );
  4481 		$plugin_data = reset( $plugin_data );
  4223 
  4482 
  4224 		if ( $plugin_data['Version'] ) {
  4483 		if ( $plugin_data['Version'] ) {
  4225 			/* translators: %s: Plugin version */
  4484 			/* translators: %s: Plugin version. */
  4226 			$status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
  4485 			$status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
  4227 		}
  4486 		}
       
  4487 
  4228 		wp_send_json_success( $status );
  4488 		wp_send_json_success( $status );
  4229 	} elseif ( false === $result ) {
  4489 	} elseif ( false === $result ) {
  4230 		global $wp_filesystem;
  4490 		global $wp_filesystem;
  4231 
  4491 
  4232 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4492 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4288 		wp_send_json_error( $status );
  4548 		wp_send_json_error( $status );
  4289 	}
  4549 	}
  4290 
  4550 
  4291 	// Check filesystem credentials. `delete_plugins()` will bail otherwise.
  4551 	// Check filesystem credentials. `delete_plugins()` will bail otherwise.
  4292 	$url = wp_nonce_url( 'plugins.php?action=delete-selected&verify-delete=1&checked[]=' . $plugin, 'bulk-plugins' );
  4552 	$url = wp_nonce_url( 'plugins.php?action=delete-selected&verify-delete=1&checked[]=' . $plugin, 'bulk-plugins' );
       
  4553 
  4293 	ob_start();
  4554 	ob_start();
  4294 	$credentials = request_filesystem_credentials( $url );
  4555 	$credentials = request_filesystem_credentials( $url );
  4295 	ob_end_clean();
  4556 	ob_end_clean();
       
  4557 
  4296 	if ( false === $credentials || ! WP_Filesystem( $credentials ) ) {
  4558 	if ( false === $credentials || ! WP_Filesystem( $credentials ) ) {
  4297 		global $wp_filesystem;
  4559 		global $wp_filesystem;
  4298 
  4560 
  4299 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4561 		$status['errorCode']    = 'unable_to_connect_to_filesystem';
  4300 		$status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
  4562 		$status['errorMessage'] = __( 'Unable to connect to the filesystem. Please confirm your credentials.' );
  4327  *
  4589  *
  4328  * @global string $s Search term.
  4590  * @global string $s Search term.
  4329  */
  4591  */
  4330 function wp_ajax_search_plugins() {
  4592 function wp_ajax_search_plugins() {
  4331 	check_ajax_referer( 'updates' );
  4593 	check_ajax_referer( 'updates' );
       
  4594 
       
  4595 	// Ensure after_plugin_row_{$plugin_file} gets hooked.
       
  4596 	wp_plugin_update_rows();
  4332 
  4597 
  4333 	$pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : '';
  4598 	$pagenow = isset( $_POST['pagenow'] ) ? sanitize_key( $_POST['pagenow'] ) : '';
  4334 	if ( 'plugins-network' === $pagenow || 'plugins' === $pagenow ) {
  4599 	if ( 'plugins-network' === $pagenow || 'plugins' === $pagenow ) {
  4335 		set_current_screen( $pagenow );
  4600 		set_current_screen( $pagenow );
  4336 	}
  4601 	}
  4426 
  4691 
  4427 /**
  4692 /**
  4428  * Ajax handler for editing a theme or plugin file.
  4693  * Ajax handler for editing a theme or plugin file.
  4429  *
  4694  *
  4430  * @since 4.9.0
  4695  * @since 4.9.0
       
  4696  *
  4431  * @see wp_edit_theme_plugin_file()
  4697  * @see wp_edit_theme_plugin_file()
  4432  */
  4698  */
  4433 function wp_ajax_edit_theme_plugin_file() {
  4699 function wp_ajax_edit_theme_plugin_file() {
  4434 	$r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) ); // Validation of args is done in wp_edit_theme_plugin_file().
  4700 	$r = wp_edit_theme_plugin_file( wp_unslash( $_POST ) ); // Validation of args is done in wp_edit_theme_plugin_file().
       
  4701 
  4435 	if ( is_wp_error( $r ) ) {
  4702 	if ( is_wp_error( $r ) ) {
  4436 		wp_send_json_error(
  4703 		wp_send_json_error(
  4437 			array_merge(
  4704 			array_merge(
  4438 				array(
  4705 				array(
  4439 					'code'    => $r->get_error_code(),
  4706 					'code'    => $r->get_error_code(),
  4459 function wp_ajax_wp_privacy_export_personal_data() {
  4726 function wp_ajax_wp_privacy_export_personal_data() {
  4460 
  4727 
  4461 	if ( empty( $_POST['id'] ) ) {
  4728 	if ( empty( $_POST['id'] ) ) {
  4462 		wp_send_json_error( __( 'Missing request ID.' ) );
  4729 		wp_send_json_error( __( 'Missing request ID.' ) );
  4463 	}
  4730 	}
       
  4731 
  4464 	$request_id = (int) $_POST['id'];
  4732 	$request_id = (int) $_POST['id'];
  4465 
  4733 
  4466 	if ( $request_id < 1 ) {
  4734 	if ( $request_id < 1 ) {
  4467 		wp_send_json_error( __( 'Invalid request ID.' ) );
  4735 		wp_send_json_error( __( 'Invalid request ID.' ) );
  4468 	}
  4736 	}
  4471 		wp_send_json_error( __( 'Sorry, you are not allowed to perform this action.' ) );
  4739 		wp_send_json_error( __( 'Sorry, you are not allowed to perform this action.' ) );
  4472 	}
  4740 	}
  4473 
  4741 
  4474 	check_ajax_referer( 'wp-privacy-export-personal-data-' . $request_id, 'security' );
  4742 	check_ajax_referer( 'wp-privacy-export-personal-data-' . $request_id, 'security' );
  4475 
  4743 
  4476 	// Get the request data.
  4744 	// Get the request.
  4477 	$request = wp_get_user_request_data( $request_id );
  4745 	$request = wp_get_user_request( $request_id );
  4478 
  4746 
  4479 	if ( ! $request || 'export_personal_data' !== $request->action_name ) {
  4747 	if ( ! $request || 'export_personal_data' !== $request->action_name ) {
  4480 		wp_send_json_error( __( 'Invalid request type.' ) );
  4748 		wp_send_json_error( __( 'Invalid request type.' ) );
  4481 	}
  4749 	}
  4482 
  4750 
  4486 	}
  4754 	}
  4487 
  4755 
  4488 	if ( ! isset( $_POST['exporter'] ) ) {
  4756 	if ( ! isset( $_POST['exporter'] ) ) {
  4489 		wp_send_json_error( __( 'Missing exporter index.' ) );
  4757 		wp_send_json_error( __( 'Missing exporter index.' ) );
  4490 	}
  4758 	}
       
  4759 
  4491 	$exporter_index = (int) $_POST['exporter'];
  4760 	$exporter_index = (int) $_POST['exporter'];
  4492 
  4761 
  4493 	if ( ! isset( $_POST['page'] ) ) {
  4762 	if ( ! isset( $_POST['page'] ) ) {
  4494 		wp_send_json_error( __( 'Missing page index.' ) );
  4763 		wp_send_json_error( __( 'Missing page index.' ) );
  4495 	}
  4764 	}
       
  4765 
  4496 	$page = (int) $_POST['page'];
  4766 	$page = (int) $_POST['page'];
  4497 
  4767 
  4498 	$send_as_email = isset( $_POST['sendAsEmail'] ) ? ( 'true' === $_POST['sendAsEmail'] ) : false;
  4768 	$send_as_email = isset( $_POST['sendAsEmail'] ) ? ( 'true' === $_POST['sendAsEmail'] ) : false;
  4499 
  4769 
  4500 	/**
  4770 	/**
  4503 	 * @since 4.9.6
  4773 	 * @since 4.9.6
  4504 	 *
  4774 	 *
  4505 	 * @param array $args {
  4775 	 * @param array $args {
  4506 	 *     An array of callable exporters of personal data. Default empty array.
  4776 	 *     An array of callable exporters of personal data. Default empty array.
  4507 	 *
  4777 	 *
  4508 	 *     @type array {
  4778 	 *     @type array ...$0 {
  4509 	 *         Array of personal data exporters.
  4779 	 *         Array of personal data exporters.
  4510 	 *
  4780 	 *
  4511 	 *         @type string $callback               Callable exporter function that accepts an
  4781 	 *         @type callable $callback               Callable exporter function that accepts an
  4512 	 *                                              email address and a page and returns an array
  4782 	 *                                                email address and a page and returns an array
  4513 	 *                                              of name => value pairs of personal data.
  4783 	 *                                                of name => value pairs of personal data.
  4514 	 *         @type string $exporter_friendly_name Translated user facing friendly name for the
  4784 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the
  4515 	 *                                              exporter.
  4785 	 *                                                exporter.
  4516 	 *     }
  4786 	 *     }
  4517 	 * }
  4787 	 * }
  4518 	 */
  4788 	 */
  4519 	$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
  4789 	$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
  4520 
  4790 
  4540 		$exporter_key  = $exporter_keys[ $exporter_index - 1 ];
  4810 		$exporter_key  = $exporter_keys[ $exporter_index - 1 ];
  4541 		$exporter      = $exporters[ $exporter_key ];
  4811 		$exporter      = $exporters[ $exporter_key ];
  4542 
  4812 
  4543 		if ( ! is_array( $exporter ) ) {
  4813 		if ( ! is_array( $exporter ) ) {
  4544 			wp_send_json_error(
  4814 			wp_send_json_error(
  4545 				/* translators: %s: exporter array index */
  4815 				/* translators: %s: Exporter array index. */
  4546 				sprintf( __( 'Expected an array describing the exporter at index %s.' ), $exporter_key )
  4816 				sprintf( __( 'Expected an array describing the exporter at index %s.' ), $exporter_key )
  4547 			);
  4817 			);
  4548 		}
  4818 		}
       
  4819 
  4549 		if ( ! array_key_exists( 'exporter_friendly_name', $exporter ) ) {
  4820 		if ( ! array_key_exists( 'exporter_friendly_name', $exporter ) ) {
  4550 			wp_send_json_error(
  4821 			wp_send_json_error(
  4551 				/* translators: %s: exporter array index */
  4822 				/* translators: %s: Exporter array index. */
  4552 				sprintf( __( 'Exporter array at index %s does not include a friendly name.' ), $exporter_key )
  4823 				sprintf( __( 'Exporter array at index %s does not include a friendly name.' ), $exporter_key )
  4553 			);
  4824 			);
  4554 		}
  4825 		}
  4555 
  4826 
  4556 		$exporter_friendly_name = $exporter['exporter_friendly_name'];
  4827 		$exporter_friendly_name = $exporter['exporter_friendly_name'];
  4557 
  4828 
  4558 		if ( ! array_key_exists( 'callback', $exporter ) ) {
  4829 		if ( ! array_key_exists( 'callback', $exporter ) ) {
  4559 			wp_send_json_error(
  4830 			wp_send_json_error(
  4560 				/* translators: %s: exporter friendly name */
  4831 				/* translators: %s: Exporter friendly name. */
  4561 				sprintf( __( 'Exporter does not include a callback: %s.' ), esc_html( $exporter_friendly_name ) )
  4832 				sprintf( __( 'Exporter does not include a callback: %s.' ), esc_html( $exporter_friendly_name ) )
  4562 			);
  4833 			);
  4563 		}
  4834 		}
       
  4835 
  4564 		if ( ! is_callable( $exporter['callback'] ) ) {
  4836 		if ( ! is_callable( $exporter['callback'] ) ) {
  4565 			wp_send_json_error(
  4837 			wp_send_json_error(
  4566 				/* translators: %s: exporter friendly name */
  4838 				/* translators: %s: Exporter friendly name. */
  4567 				sprintf( __( 'Exporter callback is not a valid callback: %s.' ), esc_html( $exporter_friendly_name ) )
  4839 				sprintf( __( 'Exporter callback is not a valid callback: %s.' ), esc_html( $exporter_friendly_name ) )
  4568 			);
  4840 			);
  4569 		}
  4841 		}
  4570 
  4842 
  4571 		$callback = $exporter['callback'];
  4843 		$callback = $exporter['callback'];
  4575 			wp_send_json_error( $response );
  4847 			wp_send_json_error( $response );
  4576 		}
  4848 		}
  4577 
  4849 
  4578 		if ( ! is_array( $response ) ) {
  4850 		if ( ! is_array( $response ) ) {
  4579 			wp_send_json_error(
  4851 			wp_send_json_error(
  4580 				/* translators: %s: exporter friendly name */
  4852 				/* translators: %s: Exporter friendly name. */
  4581 				sprintf( __( 'Expected response as an array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4853 				sprintf( __( 'Expected response as an array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4582 			);
  4854 			);
  4583 		}
  4855 		}
       
  4856 
  4584 		if ( ! array_key_exists( 'data', $response ) ) {
  4857 		if ( ! array_key_exists( 'data', $response ) ) {
  4585 			wp_send_json_error(
  4858 			wp_send_json_error(
  4586 				/* translators: %s: exporter friendly name */
  4859 				/* translators: %s: Exporter friendly name. */
  4587 				sprintf( __( 'Expected data in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4860 				sprintf( __( 'Expected data in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4588 			);
  4861 			);
  4589 		}
  4862 		}
       
  4863 
  4590 		if ( ! is_array( $response['data'] ) ) {
  4864 		if ( ! is_array( $response['data'] ) ) {
  4591 			wp_send_json_error(
  4865 			wp_send_json_error(
  4592 				/* translators: %s: exporter friendly name */
  4866 				/* translators: %s: Exporter friendly name. */
  4593 				sprintf( __( 'Expected data array in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4867 				sprintf( __( 'Expected data array in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4594 			);
  4868 			);
  4595 		}
  4869 		}
       
  4870 
  4596 		if ( ! array_key_exists( 'done', $response ) ) {
  4871 		if ( ! array_key_exists( 'done', $response ) ) {
  4597 			wp_send_json_error(
  4872 			wp_send_json_error(
  4598 				/* translators: %s: exporter friendly name */
  4873 				/* translators: %s: Exporter friendly name. */
  4599 				sprintf( __( 'Expected done (boolean) in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4874 				sprintf( __( 'Expected done (boolean) in response array from exporter: %s.' ), esc_html( $exporter_friendly_name ) )
  4600 			);
  4875 			);
  4601 		}
  4876 		}
  4602 	} else {
  4877 	} else {
  4603 		// No exporters, so we're done.
  4878 		// No exporters, so we're done.
  4655 		wp_send_json_error( __( 'Sorry, you are not allowed to perform this action.' ) );
  4930 		wp_send_json_error( __( 'Sorry, you are not allowed to perform this action.' ) );
  4656 	}
  4931 	}
  4657 
  4932 
  4658 	check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' );
  4933 	check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' );
  4659 
  4934 
  4660 	// Get the request data.
  4935 	// Get the request.
  4661 	$request = wp_get_user_request_data( $request_id );
  4936 	$request = wp_get_user_request( $request_id );
  4662 
  4937 
  4663 	if ( ! $request || 'remove_personal_data' !== $request->action_name ) {
  4938 	if ( ! $request || 'remove_personal_data' !== $request->action_name ) {
  4664 		wp_send_json_error( __( 'Invalid request type.' ) );
  4939 		wp_send_json_error( __( 'Invalid request type.' ) );
  4665 	}
  4940 	}
  4666 
  4941 
  4688 	 * @since 4.9.6
  4963 	 * @since 4.9.6
  4689 	 *
  4964 	 *
  4690 	 * @param array $args {
  4965 	 * @param array $args {
  4691 	 *     An array of callable erasers of personal data. Default empty array.
  4966 	 *     An array of callable erasers of personal data. Default empty array.
  4692 	 *
  4967 	 *
  4693 	 *     @type array {
  4968 	 *     @type array ...$0 {
  4694 	 *         Array of personal data exporters.
  4969 	 *         Array of personal data exporters.
  4695 	 *
  4970 	 *
  4696 	 *         @type string $callback               Callable eraser that accepts an email address and
  4971 	 *         @type callable $callback               Callable eraser that accepts an email address and
  4697 	 *                                              a page and returns an array with boolean values for
  4972 	 *                                                a page and returns an array with boolean values for
  4698 	 *                                              whether items were removed or retained and any messages
  4973 	 *                                                whether items were removed or retained and any messages
  4699 	 *                                              from the eraser, as well as if additional pages are
  4974 	 *                                                from the eraser, as well as if additional pages are
  4700 	 *                                              available.
  4975 	 *                                                available.
  4701 	 *         @type string $exporter_friendly_name Translated user facing friendly name for the eraser.
  4976 	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the eraser.
  4702 	 *     }
  4977 	 *     }
  4703 	 * }
  4978 	 * }
  4704 	 */
  4979 	 */
  4705 	$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
  4980 	$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
  4706 
  4981 
  4722 		$eraser_keys = array_keys( $erasers );
  4997 		$eraser_keys = array_keys( $erasers );
  4723 		$eraser_key  = $eraser_keys[ $eraser_index - 1 ];
  4998 		$eraser_key  = $eraser_keys[ $eraser_index - 1 ];
  4724 		$eraser      = $erasers[ $eraser_key ];
  4999 		$eraser      = $erasers[ $eraser_key ];
  4725 
  5000 
  4726 		if ( ! is_array( $eraser ) ) {
  5001 		if ( ! is_array( $eraser ) ) {
  4727 			/* translators: %d: eraser array index */
  5002 			/* translators: %d: Eraser array index. */
  4728 			wp_send_json_error( sprintf( __( 'Expected an array describing the eraser at index %d.' ), $eraser_index ) );
  5003 			wp_send_json_error( sprintf( __( 'Expected an array describing the eraser at index %d.' ), $eraser_index ) );
  4729 		}
  5004 		}
  4730 
  5005 
  4731 		if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) {
  5006 		if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) {
  4732 			/* translators: %d: eraser array index */
  5007 			/* translators: %d: Eraser array index. */
  4733 			wp_send_json_error( sprintf( __( 'Eraser array at index %d does not include a friendly name.' ), $eraser_index ) );
  5008 			wp_send_json_error( sprintf( __( 'Eraser array at index %d does not include a friendly name.' ), $eraser_index ) );
  4734 		}
  5009 		}
  4735 
  5010 
  4736 		$eraser_friendly_name = $eraser['eraser_friendly_name'];
  5011 		$eraser_friendly_name = $eraser['eraser_friendly_name'];
  4737 
  5012 
  4738 		if ( ! array_key_exists( 'callback', $eraser ) ) {
  5013 		if ( ! array_key_exists( 'callback', $eraser ) ) {
  4739 			wp_send_json_error(
  5014 			wp_send_json_error(
  4740 				sprintf(
  5015 				sprintf(
  4741 					/* translators: %s: eraser friendly name */
  5016 					/* translators: %s: Eraser friendly name. */
  4742 					__( 'Eraser does not include a callback: %s.' ),
  5017 					__( 'Eraser does not include a callback: %s.' ),
  4743 					esc_html( $eraser_friendly_name )
  5018 					esc_html( $eraser_friendly_name )
  4744 				)
  5019 				)
  4745 			);
  5020 			);
  4746 		}
  5021 		}
  4747 
  5022 
  4748 		if ( ! is_callable( $eraser['callback'] ) ) {
  5023 		if ( ! is_callable( $eraser['callback'] ) ) {
  4749 			wp_send_json_error(
  5024 			wp_send_json_error(
  4750 				sprintf(
  5025 				sprintf(
  4751 					/* translators: %s: eraser friendly name */
  5026 					/* translators: %s: Eraser friendly name. */
  4752 					__( 'Eraser callback is not valid: %s.' ),
  5027 					__( 'Eraser callback is not valid: %s.' ),
  4753 					esc_html( $eraser_friendly_name )
  5028 					esc_html( $eraser_friendly_name )
  4754 				)
  5029 				)
  4755 			);
  5030 			);
  4756 		}
  5031 		}
  4763 		}
  5038 		}
  4764 
  5039 
  4765 		if ( ! is_array( $response ) ) {
  5040 		if ( ! is_array( $response ) ) {
  4766 			wp_send_json_error(
  5041 			wp_send_json_error(
  4767 				sprintf(
  5042 				sprintf(
  4768 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5043 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4769 					__( 'Did not receive array from %1$s eraser (index %2$d).' ),
  5044 					__( 'Did not receive array from %1$s eraser (index %2$d).' ),
  4770 					esc_html( $eraser_friendly_name ),
  5045 					esc_html( $eraser_friendly_name ),
  4771 					$eraser_index
  5046 					$eraser_index
  4772 				)
  5047 				)
  4773 			);
  5048 			);
  4774 		}
  5049 		}
  4775 
  5050 
  4776 		if ( ! array_key_exists( 'items_removed', $response ) ) {
  5051 		if ( ! array_key_exists( 'items_removed', $response ) ) {
  4777 			wp_send_json_error(
  5052 			wp_send_json_error(
  4778 				sprintf(
  5053 				sprintf(
  4779 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5054 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4780 					__( 'Expected items_removed key in response array from %1$s eraser (index %2$d).' ),
  5055 					__( 'Expected items_removed key in response array from %1$s eraser (index %2$d).' ),
  4781 					esc_html( $eraser_friendly_name ),
  5056 					esc_html( $eraser_friendly_name ),
  4782 					$eraser_index
  5057 					$eraser_index
  4783 				)
  5058 				)
  4784 			);
  5059 			);
  4785 		}
  5060 		}
  4786 
  5061 
  4787 		if ( ! array_key_exists( 'items_retained', $response ) ) {
  5062 		if ( ! array_key_exists( 'items_retained', $response ) ) {
  4788 			wp_send_json_error(
  5063 			wp_send_json_error(
  4789 				sprintf(
  5064 				sprintf(
  4790 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5065 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4791 					__( 'Expected items_retained key in response array from %1$s eraser (index %2$d).' ),
  5066 					__( 'Expected items_retained key in response array from %1$s eraser (index %2$d).' ),
  4792 					esc_html( $eraser_friendly_name ),
  5067 					esc_html( $eraser_friendly_name ),
  4793 					$eraser_index
  5068 					$eraser_index
  4794 				)
  5069 				)
  4795 			);
  5070 			);
  4796 		}
  5071 		}
  4797 
  5072 
  4798 		if ( ! array_key_exists( 'messages', $response ) ) {
  5073 		if ( ! array_key_exists( 'messages', $response ) ) {
  4799 			wp_send_json_error(
  5074 			wp_send_json_error(
  4800 				sprintf(
  5075 				sprintf(
  4801 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5076 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4802 					__( 'Expected messages key in response array from %1$s eraser (index %2$d).' ),
  5077 					__( 'Expected messages key in response array from %1$s eraser (index %2$d).' ),
  4803 					esc_html( $eraser_friendly_name ),
  5078 					esc_html( $eraser_friendly_name ),
  4804 					$eraser_index
  5079 					$eraser_index
  4805 				)
  5080 				)
  4806 			);
  5081 			);
  4807 		}
  5082 		}
  4808 
  5083 
  4809 		if ( ! is_array( $response['messages'] ) ) {
  5084 		if ( ! is_array( $response['messages'] ) ) {
  4810 			wp_send_json_error(
  5085 			wp_send_json_error(
  4811 				sprintf(
  5086 				sprintf(
  4812 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5087 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4813 					__( 'Expected messages key to reference an array in response array from %1$s eraser (index %2$d).' ),
  5088 					__( 'Expected messages key to reference an array in response array from %1$s eraser (index %2$d).' ),
  4814 					esc_html( $eraser_friendly_name ),
  5089 					esc_html( $eraser_friendly_name ),
  4815 					$eraser_index
  5090 					$eraser_index
  4816 				)
  5091 				)
  4817 			);
  5092 			);
  4818 		}
  5093 		}
  4819 
  5094 
  4820 		if ( ! array_key_exists( 'done', $response ) ) {
  5095 		if ( ! array_key_exists( 'done', $response ) ) {
  4821 			wp_send_json_error(
  5096 			wp_send_json_error(
  4822 				sprintf(
  5097 				sprintf(
  4823 					/* translators: 1: eraser friendly name, 2: eraser array index */
  5098 					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
  4824 					__( 'Expected done flag in response array from %1$s eraser (index %2$d).' ),
  5099 					__( 'Expected done flag in response array from %1$s eraser (index %2$d).' ),
  4825 					esc_html( $eraser_friendly_name ),
  5100 					esc_html( $eraser_friendly_name ),
  4826 					$eraser_index
  5101 					$eraser_index
  4827 				)
  5102 				)
  4828 			);
  5103 			);
  4873 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  5148 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  4874 		wp_send_json_error();
  5149 		wp_send_json_error();
  4875 	}
  5150 	}
  4876 
  5151 
  4877 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  5152 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  4878 		require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
  5153 		require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
  4879 	}
  5154 	}
  4880 
  5155 
  4881 	$site_health = new WP_Site_Health();
  5156 	$site_health = WP_Site_Health::get_instance();
  4882 	wp_send_json_success( $site_health->get_test_dotorg_communication() );
  5157 	wp_send_json_success( $site_health->get_test_dotorg_communication() );
  4883 }
  5158 }
  4884 
  5159 
  4885 /**
  5160 /**
  4886  * Ajax handler for site health checks on debug mode.
  5161  * Ajax handler for site health checks on debug mode.
  4893 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  5168 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  4894 		wp_send_json_error();
  5169 		wp_send_json_error();
  4895 	}
  5170 	}
  4896 
  5171 
  4897 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  5172 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  4898 		require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
  5173 		require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
  4899 	}
  5174 	}
  4900 
  5175 
  4901 	$site_health = new WP_Site_Health();
  5176 	$site_health = WP_Site_Health::get_instance();
  4902 	wp_send_json_success( $site_health->get_test_is_in_debug_mode() );
  5177 	wp_send_json_success( $site_health->get_test_is_in_debug_mode() );
  4903 }
  5178 }
  4904 
  5179 
  4905 /**
  5180 /**
  4906  * Ajax handler for site health checks on background updates.
  5181  * Ajax handler for site health checks on background updates.
  4913 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  5188 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  4914 		wp_send_json_error();
  5189 		wp_send_json_error();
  4915 	}
  5190 	}
  4916 
  5191 
  4917 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  5192 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  4918 		require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
  5193 		require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
  4919 	}
  5194 	}
  4920 
  5195 
  4921 	$site_health = new WP_Site_Health();
  5196 	$site_health = WP_Site_Health::get_instance();
  4922 	wp_send_json_success( $site_health->get_test_background_updates() );
  5197 	wp_send_json_success( $site_health->get_test_background_updates() );
  4923 }
  5198 }
  4924 
       
  4925 
  5199 
  4926 /**
  5200 /**
  4927  * Ajax handler for site health checks on loopback requests.
  5201  * Ajax handler for site health checks on loopback requests.
  4928  *
  5202  *
  4929  * @since 5.2.0
  5203  * @since 5.2.0
  4934 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  5208 	if ( ! current_user_can( 'view_site_health_checks' ) ) {
  4935 		wp_send_json_error();
  5209 		wp_send_json_error();
  4936 	}
  5210 	}
  4937 
  5211 
  4938 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  5212 	if ( ! class_exists( 'WP_Site_Health' ) ) {
  4939 		require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
  5213 		require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
  4940 	}
  5214 	}
  4941 
  5215 
  4942 	$site_health = new WP_Site_Health();
  5216 	$site_health = WP_Site_Health::get_instance();
  4943 	wp_send_json_success( $site_health->get_test_loopback_requests() );
  5217 	wp_send_json_success( $site_health->get_test_loopback_requests() );
  4944 }
  5218 }
  4945 
  5219 
  4946 /**
  5220 /**
  4947  * Ajax handler for site health check to update the result status.
  5221  * Ajax handler for site health check to update the result status.
  4971 	if ( ! current_user_can( 'view_site_health_checks' ) || is_multisite() ) {
  5245 	if ( ! current_user_can( 'view_site_health_checks' ) || is_multisite() ) {
  4972 		wp_send_json_error();
  5246 		wp_send_json_error();
  4973 	}
  5247 	}
  4974 
  5248 
  4975 	if ( ! class_exists( 'WP_Debug_Data' ) ) {
  5249 	if ( ! class_exists( 'WP_Debug_Data' ) ) {
  4976 		require_once( ABSPATH . 'wp-admin/includes/class-wp-debug-data.php' );
  5250 		require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
  4977 	}
  5251 	}
  4978 
  5252 
  4979 	$sizes_data = WP_Debug_Data::get_sizes();
  5253 	$sizes_data = WP_Debug_Data::get_sizes();
  4980 	$all_sizes  = array( 'raw' => 0 );
  5254 	$all_sizes  = array( 'raw' => 0 );
  4981 
  5255 
  5010 		wp_send_json_error( $all_sizes );
  5284 		wp_send_json_error( $all_sizes );
  5011 	}
  5285 	}
  5012 
  5286 
  5013 	wp_send_json_success( $all_sizes );
  5287 	wp_send_json_success( $all_sizes );
  5014 }
  5288 }
       
  5289 
       
  5290 /**
       
  5291  * Ajax handler to renew the REST API nonce.
       
  5292  *
       
  5293  * @since 5.3.0
       
  5294  */
       
  5295 function wp_ajax_rest_nonce() {
       
  5296 	exit( wp_create_nonce( 'wp_rest' ) );
       
  5297 }
       
  5298 
       
  5299 /**
       
  5300  * Ajax handler to enable or disable plugin and theme auto-updates.
       
  5301  *
       
  5302  * @since 5.5.0
       
  5303  */
       
  5304 function wp_ajax_toggle_auto_updates() {
       
  5305 	check_ajax_referer( 'updates' );
       
  5306 
       
  5307 	if ( empty( $_POST['type'] ) || empty( $_POST['asset'] ) || empty( $_POST['state'] ) ) {
       
  5308 		wp_send_json_error( array( 'error' => __( 'Invalid data. No selected item.' ) ) );
       
  5309 	}
       
  5310 
       
  5311 	$asset = sanitize_text_field( urldecode( $_POST['asset'] ) );
       
  5312 
       
  5313 	if ( 'enable' !== $_POST['state'] && 'disable' !== $_POST['state'] ) {
       
  5314 		wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown state.' ) ) );
       
  5315 	}
       
  5316 	$state = $_POST['state'];
       
  5317 
       
  5318 	if ( 'plugin' !== $_POST['type'] && 'theme' !== $_POST['type'] ) {
       
  5319 		wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown type.' ) ) );
       
  5320 	}
       
  5321 	$type = $_POST['type'];
       
  5322 
       
  5323 	switch ( $type ) {
       
  5324 		case 'plugin':
       
  5325 			if ( ! current_user_can( 'update_plugins' ) ) {
       
  5326 				$error_message = __( 'Sorry, you are not allowed to modify plugins.' );
       
  5327 				wp_send_json_error( array( 'error' => $error_message ) );
       
  5328 			}
       
  5329 
       
  5330 			$option = 'auto_update_plugins';
       
  5331 			/** This filter is documented in wp-admin/includes/class-wp-plugins-list-table.php */
       
  5332 			$all_items = apply_filters( 'all_plugins', get_plugins() );
       
  5333 			break;
       
  5334 		case 'theme':
       
  5335 			if ( ! current_user_can( 'update_themes' ) ) {
       
  5336 				$error_message = __( 'Sorry, you are not allowed to modify themes.' );
       
  5337 				wp_send_json_error( array( 'error' => $error_message ) );
       
  5338 			}
       
  5339 
       
  5340 			$option    = 'auto_update_themes';
       
  5341 			$all_items = wp_get_themes();
       
  5342 			break;
       
  5343 		default:
       
  5344 			wp_send_json_error( array( 'error' => __( 'Invalid data. Unknown type.' ) ) );
       
  5345 	}
       
  5346 
       
  5347 	if ( ! array_key_exists( $asset, $all_items ) ) {
       
  5348 		$error_message = __( 'Invalid data. The item does not exist.' );
       
  5349 		wp_send_json_error( array( 'error' => $error_message ) );
       
  5350 	}
       
  5351 
       
  5352 	$auto_updates = (array) get_site_option( $option, array() );
       
  5353 
       
  5354 	if ( 'disable' === $state ) {
       
  5355 		$auto_updates = array_diff( $auto_updates, array( $asset ) );
       
  5356 	} else {
       
  5357 		$auto_updates[] = $asset;
       
  5358 		$auto_updates   = array_unique( $auto_updates );
       
  5359 	}
       
  5360 
       
  5361 	// Remove items that have been deleted since the site option was last updated.
       
  5362 	$auto_updates = array_intersect( $auto_updates, array_keys( $all_items ) );
       
  5363 
       
  5364 	update_site_option( $option, $auto_updates );
       
  5365 
       
  5366 	wp_send_json_success();
       
  5367 }