阐述 WordPress `wp_get_post_revisions()` 函数的源码:如何获取文章的所有修订版本。

各位观众老爷,晚上好!今天咱就来聊聊WordPress里一个挺低调但关键的函数:wp_get_post_revisions()。这函数就像个历史学家,专门负责挖掘文章的各种修订版本,让咱们能回溯过去,找回那些被修改、删除的内容。

1. 啥是文章修订?为啥要有它?

在WordPress里,每次你保存或自动保存一篇文章(post),系统都会默默地保存一个“修订”(revision)。这就像给文章拍快照,记录下当时的模样。

那为啥要这么做呢?理由嘛,很简单:

  • 后悔药: 谁还没个手滑的时候?万一改错了,能轻松回滚到之前的版本。
  • 追踪修改: 团队协作写文章,能清楚地看到谁做了啥修改。
  • 灵感来源: 有时候旧版本里的一些内容,能给你带来新的灵感。

2. wp_get_post_revisions():时间机器的遥控器

wp_get_post_revisions() 函数就是咱们控制这个“时间机器”的遥控器。它能帮咱们获取指定文章的所有修订版本。

3. 源码解析:一层层扒开它的外衣

咱们直接深入源码,看看这函数到底是怎么工作的。

/**
 * Retrieve revisions for a given post.
 *
 * @since 2.6.0
 *
 * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is the current post.
 * @param array       $args {
 *     Optional. An array of arguments.
 *
 *     @type string $orderby       Field to order revisions by. Accepts 'date', 'ID', 'author', 'title', 'modified',
 *                                 'menu_order', 'comment_count', 'rand', 'none'. Default 'date'.
 *     @type string $order         Whether to order revisions ascending or descending. Accepts 'ASC', 'DESC'.
 *                                 Default 'DESC'.
 *     @type int    $posts_per_page Number of revisions to return. Default -1 (all).
 *     @type int    $offset        Number of revisions to skip. Default 0.
 *     @type string $fields        Which fields to return. Accepts 'ids', 'names', '*' (all). Default '*'.
 * }
 * @return WP_Post[]|int[] Array of revisions.
 */
function wp_get_post_revisions( $post = null, $args = array() ) {
    $post = get_post( $post );

    if ( ! $post ) {
        return array();
    }

    $defaults = array(
        'orderby'        => 'date',
        'order'          => 'DESC',
        'posts_per_page' => -1,
        'offset'         => 0,
        'fields'         => '*',
    );

    $args = wp_parse_args( $args, $defaults );

    $args['post_parent'] = $post->ID;
    $args['post_type']   = 'revision';
    $args['post_status'] = 'inherit';

    return get_children( $args );
}

别慌,咱们一步步来。

3.1 参数:告诉函数你想找啥

  • $post (可选): 你想找哪个文章的修订? 可以是文章ID(整数),也可以是 WP_Post 对象。如果不传,默认是当前文章。
  • $args (可选): 一个数组,用来控制返回哪些修订,怎么排序等等。就像给SQL查询加条件。 里面可以包含以下参数:
    • orderby: 按哪个字段排序? 比如 ‘date’ (日期,默认), ‘ID’, ‘author’ (作者), ‘title'(标题), ‘modified'(修改时间), ‘menu_order’, ‘comment_count’, ‘rand’ (随机), ‘none’。
    • order: 升序 (‘ASC’) 还是降序 (‘DESC’,默认)。
    • posts_per_page: 最多返回多少个修订? -1 表示全部返回(默认)。
    • offset: 跳过多少个修订?
    • fields: 返回哪些字段? ‘ids’ (只返回ID), ‘names’ (只返回标题), ‘*’ (返回所有字段,默认)。

3.2 源码拆解

  1. 获取文章对象:$post = get_post( $post );

    首先,它会用 get_post() 函数来确保 $post 是一个有效的 WP_Post 对象。 如果 $post 传的是ID,get_post() 会根据ID获取文章对象;如果传的是 WP_Post 对象,那就直接用;如果 $postnull 或者无效的ID,get_post() 会返回 null

    $post = get_post( $post );
    
    if ( ! $post ) {
        return array(); // 如果文章不存在,直接返回空数组
    }
  2. 设置默认参数:$defaults = array(...);

    定义一个包含默认值的数组。如果 $args 里没设置某些参数,就用这些默认值。

    $defaults = array(
        'orderby'        => 'date',
        'order'          => 'DESC',
        'posts_per_page' => -1,
        'offset'         => 0,
        'fields'         => '*',
    );
  3. 合并参数:$args = wp_parse_args( $args, $defaults );

    wp_parse_args() 函数把用户传入的 $args 和默认参数 $defaults 合并起来。wp_parse_args() 会把 $args 里有的参数保留,没有的参数用 $defaults 里的值填充。

    $args = wp_parse_args( $args, $defaults );
  4. 设置查询条件:$args['post_parent'] = ...;

    关键的一步! 设置查询参数,指定只查找指定文章的修订版本。 所有的修订版本都是文章的“孩子”(post_parent)。 同时,指定文章类型是 ‘revision’,状态是 ‘inherit’。

    $args['post_parent'] = $post->ID; // 找到父文章是当前文章ID的修订版本
    $args['post_type']   = 'revision'; // 只查找文章类型是 'revision' 的
    $args['post_status'] = 'inherit'; // 状态是 'inherit' (继承父文章的状态)
  5. 获取修订版本:return get_children( $args );

    最后,调用 get_children() 函数来获取所有符合条件的修订版本。 get_children() 是一个通用的函数,用来获取指定文章的子文章(包括修订版本、附件等等)。

    return get_children( $args ); // 返回所有符合条件的修订版本

4. get_children():背后的功臣

wp_get_post_revisions() 函数的核心是 get_children()。 咱们简单看看 get_children() 做了些啥:

  • 构建SQL查询: 根据传入的 $args,构建一个复杂的SQL查询语句,从数据库里查找符合条件的文章。
  • 缓存: 为了提高效率,它会先检查缓存里有没有已经查询过的结果,如果有就直接返回缓存里的数据,否则才去数据库查询。
  • 返回结果: 把查询结果转换成 WP_Post 对象或者ID数组,然后返回。

5. 使用示例:Show me the code!

<?php
// 获取文章ID为 123 的所有修订版本
$revisions = wp_get_post_revisions( 123 );

if ( $revisions ) {
    echo '<ul>';
    foreach ( $revisions as $revision ) {
        echo '<li>';
        echo '<a href="' . get_permalink( $revision->ID ) . '">'; // 创建指向修订版本的链接
        echo '修订版本 ID: ' . $revision->ID . ', 修改时间: ' . get_the_date( '', $revision->ID );
        echo '</a>';
        echo '</li>';
    }
    echo '</ul>';
} else {
    echo '这篇文章没有修订版本。';
}

// 获取当前文章的最后 5 个修订版本,按修改时间升序排列
$args = array(
    'posts_per_page' => 5,
    'orderby'        => 'modified',
    'order'          => 'ASC',
);
$revisions = wp_get_post_revisions( null, $args ); // null 表示当前文章

// 只获取修订版本的 ID
$args = array(
    'fields' => 'ids',
);
$revision_ids = wp_get_post_revisions( 456, $args ); // 456是文章ID
?>

6. 实际应用场景:让历史重现

  • 版本回滚: 做一个“恢复到此版本”的功能,让用户可以把文章恢复到之前的某个状态。
  • 差异对比: 比较两个修订版本之间的差异,高亮显示修改的内容。
  • 历史记录展示: 在文章编辑页面,展示一个历史记录列表,方便用户查看和选择。

7. 注意事项:别玩脱了!

  • 性能: 如果文章有很多修订版本,获取所有修订版本可能会影响性能。所以,尽量限制返回的数量,或者使用缓存。
  • 权限: 只有有权限编辑文章的用户才能查看和恢复修订版本。
  • 自动保存: WordPress会自动保存文章,所以修订版本会越来越多。 可以通过 WP_POST_REVISIONS 常量来控制保存的修订版本数量,或者禁用自动保存。 在wp-config.php中设置:

    define( 'WP_POST_REVISIONS', 3 ); //  只保留最新的 3 个修订版本
    // 或者
    define( 'WP_POST_REVISIONS', false ); // 禁用修订版本

8. 表格总结:参数一览

参数名 类型 默认值 描述
$post int|WP_Post 当前文章 要获取修订版本的文章 ID 或 WP_Post 对象。
$args['orderby'] string ‘date’ 排序字段。 可选值:’date’, ‘ID’, ‘author’, ‘title’, ‘modified’, ‘menu_order’, ‘comment_count’, ‘rand’, ‘none’。
$args['order'] string ‘DESC’ 排序方式。可选值:’ASC’, ‘DESC’。
$args['posts_per_page'] int -1 每页显示的数量。-1 表示所有。
$args['offset'] int 0 偏移量,跳过多少个修订版本。
$args['fields'] string ‘*’ 返回的字段。可选值:’ids’, ‘names’, ‘*’。

9. 结束语:掌握历史,才能创造未来

wp_get_post_revisions() 函数就像一个时光机,能带咱们回到过去,找回那些被遗忘的灵感和内容。掌握了这个函数,就能更好地管理文章,避免手滑带来的损失,还能为用户提供更强大的版本控制功能。 希望今天的讲解对大家有所帮助,咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注