大家好,欢迎来到今天的“WordPress源码解剖大会”。今天咱们要聊的是一个大家伙,但又有点默默无闻的角色:WP_Post_Revisions
类。 它就像一个负责任的图书管理员,默默记录着你文章的每一次修改,确保你永远不会丢失任何灵感火花。
今天我们不搞虚的,直接深入到WP_Post_Revisions
的源码腹地,看看它是如何管理WordPress文章修订版本的。准备好了吗?发车!
开场白:修订版,你的时光机
在WordPress里,修订版就像文章的时光机,让你随时可以回到过去,找回曾经的灵感。它不仅能帮你找回误删的内容,还能让你看到文章的演变过程。但这一切的幕后功臣就是WP_Post_Revisions
这个类。
WP_Post_Revisions
类概览
虽然 WordPress 核心并没有一个名为 WP_Post_Revisions
的类,但是与修订版相关的操作都是通过 wp-includes/revision.php
文件中的一系列函数来实现的。为了方便讲解,我们就假设存在一个 WP_Post_Revisions
类,它包含了这些函数的逻辑。
/**
* 虚拟的 WP_Post_Revisions 类
* 用于演示修订版管理逻辑
*/
class WP_Post_Revisions {
/**
* 创建修订版
*
* @param int $post_id Post ID.
* @param bool $autosave Optional. Whether this is an autosave. Default is false.
* @return int|WP_Error The post ID of the revision, or a WP_Error on failure.
*/
public static function create_revision( $post_id, $autosave = false ) {
// ... (实际创建修订版的代码) ...
}
/**
* 获取文章的修订版
*
* @param int $post_id Post ID.
* @param array|string $args Optional. Array or string of arguments. See WP_Query::parse_query() for information on accepted arguments.
* @return WP_Query|false WP_Query instance, or false if no revisions exist.
*/
public static function get_revisions( $post_id, $args = array() ) {
// ... (实际获取修订版的代码) ...
}
/**
* 恢复修订版
*
* @param int $revision_id Revision ID.
* @return int|WP_Error The post ID of the restored post, or a WP_Error on failure.
*/
public static function restore_revision( $revision_id ) {
// ... (实际恢复修订版的代码) ...
}
/**
* 删除修订版
*
* @param int $post_id Post ID.
* @return void
*/
public static function delete_revisions( $post_id ) {
// ... (实际删除修订版的代码) ...
}
}
1. 创建修订版:create_revision()
这是修订版管理的核心函数,它负责在文章被修改时创建新的修订版本。
-
触发时机:
- 文章保存/发布时(
wp_insert_post()
钩子) - 自动保存时
- 文章保存/发布时(
-
主要步骤:
-
检查是否需要创建修订版:
- 判断是否启用了修订版功能 (
WP_POST_REVISIONS
常量,默认为true
或一个整数,表示保留的最大修订版本数)。 - 检查文章类型是否支持修订版 (
supports( $post_type, 'revisions' )
)。 - 判断当前用户是否有权限修改文章。
- 排除自动保存 (
$autosave
参数 )。 - 比较当前文章内容与上一个修订版的内容,如果差异不大,则不创建新的修订版。 这可以避免频繁的保存操作产生大量冗余的修订版本。
- 判断是否启用了修订版功能 (
-
创建修订版文章:
- 使用
wp_insert_post()
函数创建一个新的文章,其post_type
设置为revision
。 - 将原始文章的
post_title
,post_content
,post_excerpt
,post_author
等关键字段复制到修订版文章中。 - 设置修订版文章的
post_parent
为原始文章的 ID,建立父子关系。 - 使用
_wp_put_post_revision_version()
函数将修订版的版本号(通常是时间戳)存储为文章元数据。
- 使用
-
清理旧的修订版:
- 如果启用了修订版数量限制,则删除超出限制的旧修订版。
- 使用
wp_delete_post_revision()
函数删除旧的修订版。
-
代码示例 (简化版):
/**
* 虚拟的 WP_Post_Revisions::create_revision()
*/
public static function create_revision( $post_id, $autosave = false ) {
// 1. 获取文章对象
$post = get_post( $post_id );
// 2. 检查是否需要创建修订版 (省略了详细的检查)
if ( $autosave || !post_type_supports( $post->post_type, 'revisions' ) ) {
return false;
}
// 3. 创建修订版文章
$revision = array(
'post_title' => $post->post_title,
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_author' => $post->post_author,
'post_status' => 'inherit', // 修订版的状态为 inherit
'post_type' => 'revision',
'post_parent' => $post_id,
'menu_order' => time(), // 使用时间戳作为修订版的排序依据
'comment_status' => 'closed',
'ping_status' => 'closed',
);
// 插入修订版文章
$revision_id = wp_insert_post( $revision );
if ( is_wp_error( $revision_id ) ) {
return $revision_id;
}
// 将原始文章的所有自定义字段复制到修订版
$custom_fields = get_post_custom( $post_id );
foreach ( $custom_fields as $key => $values ) {
foreach ( $values as $value ) {
update_post_meta( $revision_id, $key, maybe_serialize( $value ) );
}
}
// 4. 清理旧的修订版 (省略了详细的清理逻辑)
return $revision_id;
}
2. 获取修订版:get_revisions()
这个函数负责获取指定文章的所有修订版本。
-
参数:
$post_id
:要获取修订版本的文章 ID。$args
:可选参数,用于自定义查询条件,例如排序方式、数量限制等。
-
主要步骤:
-
构建查询参数:
- 设置
post_type
为revision
。 - 设置
post_parent
为要查询的文章 ID。 - 根据
$args
参数设置其他查询条件,例如排序方式 (orderby
)、排序方向 (order
)、每页显示的数量 (posts_per_page
) 等。
- 设置
-
执行查询:
- 使用
WP_Query
类执行查询,获取符合条件的修订版文章。
- 使用
-
返回结果:
- 返回一个
WP_Query
对象,其中包含了查询到的修订版文章。
- 返回一个
-
代码示例 (简化版):
/**
* 虚拟的 WP_Post_Revisions::get_revisions()
*/
public static function get_revisions( $post_id, $args = array() ) {
$defaults = array(
'post_parent' => $post_id,
'post_type' => 'revision',
'posts_per_page' => -1, // 获取所有修订版
'orderby' => 'menu_order', // 按修订版创建时间排序
'order' => 'DESC',
'fields' => 'ids', // 只获取 ID
);
$args = wp_parse_args( $args, $defaults );
$revisions_query = new WP_Query( $args );
return $revisions_query;
}
3. 恢复修订版:restore_revision()
这个函数负责将指定的修订版本恢复为当前文章的内容。
-
参数:
$revision_id
:要恢复的修订版文章 ID。
-
主要步骤:
-
获取修订版文章:
- 使用
get_post()
函数获取修订版文章对象。
- 使用
-
获取原始文章:
- 使用
get_post()
函数获取原始文章对象,通过修订版文章的post_parent
属性可以找到原始文章的 ID。
- 使用
-
更新原始文章内容:
- 将修订版文章的
post_title
,post_content
,post_excerpt
等关键字段复制到原始文章中。 - 更新原始文章的
post_modified
和post_modified_gmt
字段,表示文章已被修改。
- 将修订版文章的
-
更新原始文章的自定义字段:
- 删除原始文章的所有自定义字段。
- 将修订版文章的所有自定义字段复制到原始文章中。
-
更新文章:
- 使用
wp_update_post()
函数更新原始文章。
- 使用
-
代码示例 (简化版):
/**
* 虚拟的 WP_Post_Revisions::restore_revision()
*/
public static function restore_revision( $revision_id ) {
// 1. 获取修订版文章
$revision = get_post( $revision_id );
// 2. 获取原始文章
$post = get_post( $revision->post_parent );
// 3. 更新原始文章内容
$post->post_title = $revision->post_title;
$post->post_content = $revision->post_content;
$post->post_excerpt = $revision->post_excerpt;
// 4. 更新文章
$result = wp_update_post( $post );
// 5. 更新自定义字段 (省略了详细的自定义字段更新逻辑)
return $result;
}
4. 删除修订版:delete_revisions()
这个函数负责删除指定文章的所有修订版本。
-
参数:
$post_id
:要删除修订版本的文章 ID。
-
主要步骤:
-
获取所有修订版:
- 使用
get_revisions()
函数获取指定文章的所有修订版本。
- 使用
-
删除修订版:
- 遍历所有修订版文章,使用
wp_delete_post()
函数删除每个修订版文章。
- 遍历所有修订版文章,使用
-
代码示例 (简化版):
/**
* 虚拟的 WP_Post_Revisions::delete_revisions()
*/
public static function delete_revisions( $post_id ) {
$revisions_query = self::get_revisions( $post_id );
if ( $revisions_query->have_posts() ) {
while ( $revisions_query->have_posts() ) {
$revisions_query->the_post();
$revision_id = get_the_ID();
wp_delete_post( $revision_id, true ); // true 表示强制删除,不放入回收站
}
wp_reset_postdata();
}
}
修订版的存储方式
修订版实际上也是一种 post
类型,只不过它的 post_type
是 revision
,并且它的 post_status
是 inherit
。
字段 | 描述 |
---|---|
post_type |
revision ,表示这是一个修订版。 |
post_status |
inherit ,表示继承父文章的状态。 |
post_parent |
原始文章的 ID,表示这个修订版属于哪个文章。 |
menu_order |
修订版的版本号,通常是时间戳,用于排序。 |
修订版与自动保存
自动保存 (autosave) 也是一种特殊的修订版。它们之间的区别在于:
- 自动保存是临时的,通常在用户离开编辑页面时被删除。
- 修订版是永久的,除非手动删除。
创建自动保存时,create_revision()
函数的 $autosave
参数会被设置为 true
。
如何控制修订版
-
WP_POST_REVISIONS
常量: 可以在wp-config.php
文件中定义WP_POST_REVISIONS
常量来控制修订版的行为。true
(默认): 保存所有修订版。false
: 禁用修订版功能。- 整数: 限制每个文章保留的最大修订版本数。
-
revisions
支持: 可以在注册文章类型时,使用supports()
函数来声明文章类型是否支持修订版。add_action( 'init', 'my_custom_post_type' ); function my_custom_post_type() { register_post_type( 'my_post_type', array( 'labels' => array( 'name' => __( 'My Post Types' ), 'singular_name' => __( 'My Post Type' ) ), 'public' => true, 'supports' => array( 'title', 'editor', 'revisions' ) // 声明支持修订版 ) ); }
总结
WP_Post_Revisions
类(或者说相关的函数)是 WordPress 修订版管理的核心。它通过创建、获取、恢复和删除修订版文章,实现了文章历史版本的管理。 理解了这些核心函数的工作原理,你就能更好地掌握 WordPress 的文章管理机制,甚至可以根据自己的需求定制修订版功能。
希望今天的“源码解剖大会”能让你对 WordPress 的修订版管理有更深入的了解。记住,源码的世界充满了乐趣,勇敢地去探索吧! 下课!