函数文档

wp_create_post_autosave()

💡 云策文档标注

概述

wp_create_post_autosave() 函数用于从 $_POST 数据为指定文章创建自动保存数据。它处理参数转换、数据验证,并管理每个作者的自动保存版本,包括覆盖旧版本或删除无变化的自动保存。

关键要点

  • 参数 $post_data 可以是包含文章数据的关联数组或文章 ID 整数;若为 ID,则使用 $_POST 数据。
  • 返回值为自动保存修订的 ID,错误时返回 WP_Error 或 0。
  • 每个作者仅存储一个自动保存版本,如果已存在则覆盖,但若内容与原文相同则删除自动保存。
  • 内部使用 _wp_translate_postdata()、_wp_get_allowed_postdata() 等函数处理数据,并触发 wp_creating_autosave 钩子。

代码示例

function wp_create_post_autosave( $post_data ) {
    if ( is_numeric( $post_data ) ) {
        $post_id   = $post_data;
        $post_data = $_POST;
    } else {
        $post_id = (int) $post_data['post_ID'];
    }

    $post_data = _wp_translate_postdata( true, $post_data );
    if ( is_wp_error( $post_data ) ) {
        return $post_data;
    }
    $post_data = _wp_get_allowed_postdata( $post_data );

    $post_author = get_current_user_id();

    // Store one autosave per author. If there is already an autosave, overwrite it.
    $old_autosave = wp_get_post_autosave( $post_id, $post_author );
    if ( $old_autosave ) {
        $new_autosave                = _wp_post_revision_data( $post_data, true );
        $new_autosave['ID']          = $old_autosave->ID;
        $new_autosave['post_author'] = $post_author;

        $post = get_post( $post_id );

        // If the new autosave has the same content as the post, delete the autosave.
        $autosave_is_different = false;
        foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
            if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) {
                $autosave_is_different = true;
                break;
            }
        }

        if ( ! $autosave_is_different ) {
            wp_delete_post_revision( $old_autosave->ID );
            return 0;
        }

        /**
         * Fires before an autosave is stored.
         *
         * @since 4.1.0
         * @since 6.4.0 The `$is_update` parameter was added to indicate if the autosave is being updated or was newly created.
         *
         * @param array $new_autosave Post array - the autosave that is about to be saved.
         * @param bool  $is_update    Whether this is an existing autosave.
         */
        do_action( 'wp_creating_autosave', $new_autosave, true );
        return wp_update_post( $new_autosave );
    }

    // _wp_put_post_revision() expects unescaped.
    $post_data = wp_unslash( $post_data );

    // Otherwise create the new autosave as a special post revision.
    $revision = _wp_put_post_revision( $post_data, true );

    if ( ! is_wp_error( $revision ) && 0 !== $revision ) {

        /** This action is documented in wp-admin/includes/post.php */
        do_action( 'wp_creating_autosave', get_post( $revision, ARRAY_A ), false );
    }

    return $revision;
}

注意事项

  • 函数依赖于 $_POST 数据,使用时需确保数据已正确设置。
  • 自动保存内容与原文比较时使用 normalize_whitespace() 处理空白字符,以避免误判。
  • 错误处理通过 is_wp_error() 检查,开发者应妥善处理返回值。

📄 原文内容

Creates autosave data for the specified post from $_POST data.

Parameters

$post_dataarray|intrequired
Associative array containing the post data, or integer post ID.
If a numeric post ID is provided, will use the $_POST superglobal.

Return

int|WP_Error The autosave revision ID. WP_Error or 0 on error.

Source

function wp_create_post_autosave( $post_data ) {
	if ( is_numeric( $post_data ) ) {
		$post_id   = $post_data;
		$post_data = $_POST;
	} else {
		$post_id = (int) $post_data['post_ID'];
	}

	$post_data = _wp_translate_postdata( true, $post_data );
	if ( is_wp_error( $post_data ) ) {
		return $post_data;
	}
	$post_data = _wp_get_allowed_postdata( $post_data );

	$post_author = get_current_user_id();

	// Store one autosave per author. If there is already an autosave, overwrite it.
	$old_autosave = wp_get_post_autosave( $post_id, $post_author );
	if ( $old_autosave ) {
		$new_autosave                = _wp_post_revision_data( $post_data, true );
		$new_autosave['ID']          = $old_autosave->ID;
		$new_autosave['post_author'] = $post_author;

		$post = get_post( $post_id );

		// If the new autosave has the same content as the post, delete the autosave.
		$autosave_is_different = false;
		foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
			if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) {
				$autosave_is_different = true;
				break;
			}
		}

		if ( ! $autosave_is_different ) {
			wp_delete_post_revision( $old_autosave->ID );
			return 0;
		}

		/**
		 * Fires before an autosave is stored.
		 *
		 * @since 4.1.0
		 * @since 6.4.0 The `$is_update` parameter was added to indicate if the autosave is being updated or was newly created.
		 *
		 * @param array $new_autosave Post array - the autosave that is about to be saved.
		 * @param bool  $is_update    Whether this is an existing autosave.
		 */
		do_action( 'wp_creating_autosave', $new_autosave, true );
		return wp_update_post( $new_autosave );
	}

	// _wp_put_post_revision() expects unescaped.
	$post_data = wp_unslash( $post_data );

	// Otherwise create the new autosave as a special post revision.
	$revision = _wp_put_post_revision( $post_data, true );

	if ( ! is_wp_error( $revision ) && 0 !== $revision ) {

		/** This action is documented in wp-admin/includes/post.php */
		do_action( 'wp_creating_autosave', get_post( $revision, ARRAY_A ), false );
	}

	return $revision;
}

Hooks

do_action( ‘wp_creating_autosave’, array $new_autosave, bool $is_update )

Fires before an autosave is stored.

Changelog

Version Description
2.6.0 Introduced.