函数文档

wp_ajax_add_meta()

💡 云策文档标注

概述

wp_ajax_add_meta() 是一个 WordPress AJAX 处理函数,用于通过 AJAX 请求添加或更新文章的自定义字段(meta)。它处理来自管理界面的元数据操作,包括权限验证、自动草稿处理和响应返回。

关键要点

  • 函数核心功能:通过 AJAX 处理自定义字段的添加和更新,支持从 $_POST 数据中提取元键和元值。
  • 权限检查:使用 check_ajax_referer() 验证 AJAX 请求,并通过 current_user_can() 确保用户有编辑文章或元数据的权限。
  • 自动草稿处理:如果文章状态为 'auto-draft',会先将其保存为草稿,再添加元数据,避免数据丢失。
  • 错误处理:在无效输入或权限不足时,使用 wp_die() 终止执行并返回错误代码或消息。
  • 响应机制:使用 WP_Ajax_Response 类构建 JSON 响应,包含元数据 ID 和格式化行数据,便于前端更新界面。
  • 相关函数:涉及 add_meta()、edit_post()、get_metadata_by_mid()、update_metadata_by_mid() 等核心 WordPress 函数。

代码示例

check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
$pid = (int) $_POST['post_id'];
if ( isset( $_POST['metakeyselect'] ) || isset( $_POST['metakeyinput'] ) ) {
    if ( ! current_user_can( 'edit_post', $pid ) ) {
        wp_die( -1 );
    }
    // 处理元数据添加逻辑
    $mid = add_meta( $pid );
    if ( ! $mid ) {
        wp_die( __( 'Please provide a custom field value.' ) );
    }
    $meta = get_metadata_by_mid( 'post', $mid );
    $x = new WP_Ajax_Response( array(
        'what' => 'meta',
        'id' => $mid,
        'data' => _list_meta_row( $meta, $c ),
        'position' => 1,
        'supplemental' => array( 'postid' => $pid )
    ) );
    $x->send();
}

注意事项

  • 该函数主要用于 WordPress 管理后台的 AJAX 交互,开发者应确保前端发送正确的 POST 数据和非ce验证。
  • 在自定义开发中,如需类似功能,可参考此函数逻辑,但注意直接调用可能涉及内部依赖,建议通过标准钩子或 API 操作。
  • 函数自 WordPress 3.1.0 引入,兼容性需考虑版本差异。

📄 原文内容

Handles adding meta via AJAX.

Source

function wp_ajax_add_meta() {
	check_ajax_referer( 'add-meta', '_ajax_nonce-add-meta' );
	$c    = 0;
	$pid  = (int) $_POST['post_id'];
	$post = get_post( $pid );

	if ( isset( $_POST['metakeyselect'] ) || isset( $_POST['metakeyinput'] ) ) {
		if ( ! current_user_can( 'edit_post', $pid ) ) {
			wp_die( -1 );
		}

		if ( isset( $_POST['metakeyselect'] ) && '#NONE#' === $_POST['metakeyselect'] && empty( $_POST['metakeyinput'] ) ) {
			wp_die( 1 );
		}

		// If the post is an autodraft, save the post as a draft and then attempt to save the meta.
		if ( 'auto-draft' === $post->post_status ) {
			$post_data                = array();
			$post_data['action']      = 'draft'; // Warning fix.
			$post_data['post_ID']     = $pid;
			$post_data['post_type']   = $post->post_type;
			$post_data['post_status'] = 'draft';
			$now                      = time();

			$post_data['post_title'] = sprintf(
				/* translators: 1: Post creation date, 2: Post creation time. */
				__( 'Draft created on %1$s at %2$s' ),
				gmdate( __( 'F j, Y' ), $now ),
				gmdate( __( 'g:i a' ), $now )
			);

			$pid = edit_post( $post_data );

			if ( $pid ) {
				if ( is_wp_error( $pid ) ) {
					$x = new WP_Ajax_Response(
						array(
							'what' => 'meta',
							'data' => $pid,
						)
					);
					$x->send();
				}

				$mid = add_meta( $pid );
				if ( ! $mid ) {
					wp_die( __( 'Please provide a custom field value.' ) );
				}
			} else {
				wp_die( 0 );
			}
		} else {
			$mid = add_meta( $pid );
			if ( ! $mid ) {
				wp_die( __( 'Please provide a custom field value.' ) );
			}
		}

		$meta = get_metadata_by_mid( 'post', $mid );
		$pid  = (int) $meta->post_id;
		$meta = get_object_vars( $meta );

		$x = new WP_Ajax_Response(
			array(
				'what'         => 'meta',
				'id'           => $mid,
				'data'         => _list_meta_row( $meta, $c ),
				'position'     => 1,
				'supplemental' => array( 'postid' => $pid ),
			)
		);
	} else { // Update?
		$mid   = (int) key( $_POST['meta'] );
		$key   = wp_unslash( $_POST['meta'][ $mid ]['key'] );
		$value = wp_unslash( $_POST['meta'][ $mid ]['value'] );

		if ( '' === trim( $key ) ) {
			wp_die( __( 'Please provide a custom field name.' ) );
		}

		$meta = get_metadata_by_mid( 'post', $mid );

		if ( ! $meta ) {
			wp_die( 0 ); // If meta doesn't exist.
		}

		if (
			is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
			! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
			! current_user_can( 'edit_post_meta', $meta->post_id, $key )
		) {
			wp_die( -1 );
		}

		if ( $meta->meta_value !== $value || $meta->meta_key !== $key ) {
			$u = update_metadata_by_mid( 'post', $mid, $value, $key );
			if ( ! $u ) {
				wp_die( 0 ); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
			}
		}

		$x = new WP_Ajax_Response(
			array(
				'what'         => 'meta',
				'id'           => $mid,
				'old_id'       => $mid,
				'data'         => _list_meta_row(
					array(
						'meta_key'   => $key,
						'meta_value' => $value,
						'meta_id'    => $mid,
					),
					$c
				),
				'position'     => 0,
				'supplemental' => array( 'postid' => $meta->post_id ),
			)
		);
	}
	$x->send();
}

Changelog

Version Description
3.1.0 Introduced.