函数文档

wp_ajax_find_posts()

💡 云策文档标注

概述

wp_ajax_find_posts() 是一个 WordPress AJAX 处理函数,用于在“查找文章”模态框中查询文章。它通过 AJAX 请求接收搜索参数,返回符合条件的文章列表,并以 JSON 格式响应。

关键要点

  • 函数通过 check_ajax_referer() 验证 AJAX 请求的安全性,使用 'find-posts' 随机数。
  • 查询参数包括所有公开文章类型(排除附件),支持搜索关键词,默认返回最多 50 篇文章。
  • 使用 get_posts() 执行查询,若无结果则通过 wp_send_json_error() 返回错误信息。
  • 生成包含文章标题、类型、日期和状态的 HTML 表格,并通过 wp_send_json_success() 返回成功响应。
  • 函数处理了文章状态(如发布、草稿等)和日期的格式化,确保输出安全转义。

代码示例

function wp_ajax_find_posts() {
	check_ajax_referer( 'find-posts' );

	$post_types = get_post_types( array( 'public' => true ), 'objects' );
	unset( $post_types['attachment'] );

	$args = array(
		'post_type'      => array_keys( $post_types ),
		'post_status'    => 'any',
		'posts_per_page' => 50,
	);

	$search = wp_unslash( $_POST['ps'] );

	if ( '' !== $search ) {
		$args['s'] = $search;
	}

	$posts = get_posts( $args );

	if ( ! $posts ) {
		wp_send_json_error( __( 'No items found.' ) );
	}

	$html = '' . __( 'Title' ) . '' . __( 'Type' ) . '' . __( 'Date' ) . '' . __( 'Status' ) . '';
	$alt  = '';
	foreach ( $posts as $post ) {
		$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
		$alt   = ( 'alternate' === $alt ) ? '' : 'alternate';

		switch ( $post->post_status ) {
			case 'publish':
			case 'private':
				$stat = __( 'Published' );
				break;
			case 'future':
				$stat = __( 'Scheduled' );
				break;
			case 'pending':
				$stat = __( 'Pending Review' );
				break;
			case 'draft':
				$stat = __( 'Draft' );
				break;
		}

		if ( '0000-00-00 00:00:00' === $post->post_date ) {
			$time = '';
		} else {
			/* translators: Date format in table columns, see https://www.php.net/manual/datetime.format.php */
			$time = mysql2date( __( 'Y/m/d' ), $post->post_date );
		}

		$html .= 'ID . '" name="found_post_id" value="' . esc_attr( $post->ID ) . '">';
		$html .= 'ID . '">' . esc_html( $title ) . '' . esc_html( $post_types[ $post->post_type ]->labels->singular_name ) . '' . esc_html( $time ) . '' . esc_html( $stat ) . ' ' . "nn";
	}

	$html .= '';

	wp_send_json_success( $html );
}

注意事项

  • 函数依赖于 $_POST['ps'] 参数进行搜索,需确保前端正确传递此参数。
  • 文章状态处理仅覆盖了常见状态(如 publish、draft),其他状态可能需要扩展。
  • 日期格式化使用 mysql2date(),需注意时区设置可能影响输出。
  • 输出时使用 esc_attr() 和 esc_html() 进行转义,以防止 XSS 攻击。

📄 原文内容

Handles querying posts for the Find Posts modal via AJAX.

Description

See also

  • window.findPosts

Source

function wp_ajax_find_posts() {
	check_ajax_referer( 'find-posts' );

	$post_types = get_post_types( array( 'public' => true ), 'objects' );
	unset( $post_types['attachment'] );

	$args = array(
		'post_type'      => array_keys( $post_types ),
		'post_status'    => 'any',
		'posts_per_page' => 50,
	);

	$search = wp_unslash( $_POST['ps'] );

	if ( '' !== $search ) {
		$args['s'] = $search;
	}

	$posts = get_posts( $args );

	if ( ! $posts ) {
		wp_send_json_error( __( 'No items found.' ) );
	}

	$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>';
	$alt  = '';
	foreach ( $posts as $post ) {
		$title = trim( $post->post_title ) ? $post->post_title : __( '(no title)' );
		$alt   = ( 'alternate' === $alt ) ? '' : 'alternate';

		switch ( $post->post_status ) {
			case 'publish':
			case 'private':
				$stat = __( 'Published' );
				break;
			case 'future':
				$stat = __( 'Scheduled' );
				break;
			case 'pending':
				$stat = __( 'Pending Review' );
				break;
			case 'draft':
				$stat = __( 'Draft' );
				break;
		}

		if ( '0000-00-00 00:00:00' === $post->post_date ) {
			$time = '';
		} else {
			/* translators: Date format in table columns, see https://www.php.net/manual/datetime.format.php */
			$time = mysql2date( __( 'Y/m/d' ), $post->post_date );
		}

		$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>';
		$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>' . "nn";
	}

	$html .= '</tbody></table>';

	wp_send_json_success( $html );
}

Changelog

Version Description
3.1.0 Introduced.