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

好的,没问题!咳咳… 大家好!今天咱们来聊聊 WordPress 里面一个有点儿隐秘,但有时候又非常有用的小家伙——wp_get_post_revisions() 函数。这哥们儿专门负责把文章的“时光机”给翻出来,让你看看文章之前都长啥样。

一、什么是文章修订?为什么要用它?

想象一下,你辛辛苦苦写了一篇文章,改了又改,修了又修,最后终于满意了。但是,第二天你突然觉得还是昨天第三稿的某个段落写得更好,怎么办?这时候,文章修订就派上用场了。

WordPress 会自动保存你对文章的修改,这些修改就叫做修订版本。你可以把它理解成文章的历史快照,让你随时可以回到过去,找回以前的版本。

那么,wp_get_post_revisions() 函数的作用就是:获取指定文章的所有修订版本。 就像一个时间旅行指南,带你回顾文章的演变过程。

二、wp_get_post_revisions() 函数的基本用法

这个函数用起来相当简单,就像从冰箱里拿瓶冰镇可乐一样方便。它的基本语法如下:

<?php
$revisions = wp_get_post_revisions( $post_id, $args );
?>
  • $post_id (必须): 要获取修订版本的文章 ID。 也就是说,你想看哪篇文章的“黑历史”,就把它的 ID 告诉它。
  • $args (可选): 一个数组,用于自定义查询修订版本的行为。 就像给你的时光机加装了各种配件,可以控制你想回到哪个时间点。

返回值:

  • 成功: 返回一个包含所有修订版本的文章对象数组。每个文章对象都代表一个修订版本。
  • 失败: 返回一个空数组。

三、一个简单的例子:获取文章的所有修订版本并显示标题

咱们先来个最简单的例子,获取文章 ID 为 123 的所有修订版本,并显示每个修订版本的标题。

<?php
$post_id = 123;
$revisions = wp_get_post_revisions( $post_id );

if ( ! empty( $revisions ) ) {
    echo '<ul>';
    foreach ( $revisions as $revision ) {
        echo '<li><a href="' . get_permalink( $revision->ID ) . '">' . esc_html( $revision->post_title ) . '</a></li>';
    }
    echo '</ul>';
} else {
    echo '这篇文章还没有任何修订版本。';
}
?>

这段代码做了以下几件事:

  1. 定义了要查询的文章 ID ($post_id = 123;)。
  2. 调用 wp_get_post_revisions() 函数,获取文章的所有修订版本。
  3. 判断是否获取到了修订版本。
  4. 如果获取到了,就遍历修订版本数组,并输出每个修订版本的标题。
  5. 如果没获取到,就输出提示信息。

四、$args 参数详解:高级定制你的时光旅行

$args 参数允许你更精细地控制 wp_get_post_revisions() 函数的行为。它是一个数组,可以包含以下键值对:

参数名 类型 描述 默认值
posts_per_page int 要返回的修订版本数量。 使用 -1 可以返回所有修订版本。 -1
fields string 要返回的字段。 可以是 'all' (返回所有字段) 或 'ids' (只返回修订版本的 ID)。 'all'
orderby string 排序方式。 可以是 'ID', 'post_date', 'post_title' 等。 'post_date'
order string 排序顺序。 可以是 'ASC' (升序) 或 'DESC' (降序)。 'DESC'
check_enabled bool 是否检查文章是否启用了修订功能。如果设置为 false,则会忽略文章的修订设置,直接返回所有修订版本。 谨慎使用,因为这可能会返回不应该返回的修订版本。 true

4.1 获取最新的 5 个修订版本

<?php
$post_id = 123;
$args = array(
    'posts_per_page' => 5,
);
$revisions = wp_get_post_revisions( $post_id, $args );

if ( ! empty( $revisions ) ) {
    echo '<ul>';
    foreach ( $revisions as $revision ) {
        echo '<li><a href="' . get_permalink( $revision->ID ) . '">' . esc_html( $revision->post_title ) . '</a></li>';
    }
    echo '</ul>';
} else {
    echo '这篇文章还没有任何修订版本。';
}
?>

这段代码只会获取文章 ID 为 123 的最新的 5 个修订版本。

4.2 只获取修订版本的 ID

<?php
$post_id = 123;
$args = array(
    'fields' => 'ids',
);
$revisions = wp_get_post_revisions( $post_id, $args );

if ( ! empty( $revisions ) ) {
    echo '<ul>';
    foreach ( $revisions as $revision_id ) {
        echo '<li>修订版本 ID: ' . esc_html( $revision_id ) . '</li>';
    }
    echo '</ul>';
} else {
    echo '这篇文章还没有任何修订版本。';
}
?>

这段代码只会获取文章 ID 为 123 的所有修订版本的 ID。 注意,此时 $revisions 数组中的每个元素都是一个 ID,而不是一个文章对象。

4.3 按照标题升序排列修订版本

<?php
$post_id = 123;
$args = array(
    'orderby' => 'post_title',
    'order'   => 'ASC',
);
$revisions = wp_get_post_revisions( $post_id, $args );

if ( ! empty( $revisions ) ) {
    echo '<ul>';
    foreach ( $revisions as $revision ) {
        echo '<li><a href="' . get_permalink( $revision->ID ) . '">' . esc_html( $revision->post_title ) . '</a></li>';
    }
    echo '</ul>';
} else {
    echo '这篇文章还没有任何修订版本。';
}
?>

这段代码会按照修订版本的标题升序排列。

五、深入源码:wp_get_post_revisions() 函数的内部机制

想真正理解 wp_get_post_revisions() 函数,最好的方法就是深入它的源码。 咱们来扒一扒它的底裤,看看它到底是怎么工作的。

首先,这个函数位于 wp-includes/post.php 文件中。 打开这个文件,找到 wp_get_post_revisions() 函数的定义。

function wp_get_post_revisions( $post_id = 0, $args = array() ) {
    $post = get_post( $post_id );

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

    $defaults = array(
        'posts_per_page' => -1,
        'fields'         => 'all',
        'orderby'        => 'post_date',
        'order'          => 'DESC',
        'check_enabled'  => true,
    );

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

    if ( $args['check_enabled'] && ! wp_revisions_enabled( $post ) ) {
        return array();
    }

    $query_args = array(
        'post_type'      => 'revision',
        'post_parent'    => $post->ID,
        'posts_per_page' => $args['posts_per_page'],
        'fields'         => $args['fields'],
        'orderby'        => $args['orderby'],
        'order'          => $args['order'],
        'suppress_filters' => false, // Allow filters to run on the query.
    );

    /**
     * Filters the arguments used to retrieve revisions.
     *
     * @since 4.4.0
     *
     * @param array   $query_args An array of arguments used to build the revisions query.
     * @param WP_Post $post       The post object.
     */
    $query_args = apply_filters( 'wp_get_post_revisions_args', $query_args, $post );

    $revisions = get_posts( $query_args );

    /**
     * Filters the retrieved revisions.
     *
     * @since 4.4.0
     *
     * @param WP_Post[] $revisions An array of post revisions.
     * @param WP_Post   $post      The post object.
     */
    return apply_filters( 'wp_get_post_revisions', $revisions, $post );
}

咱们一行一行地分析一下:

  1. get_post( $post_id ): 首先,它会根据传入的文章 ID 获取文章对象。如果文章不存在,就直接返回一个空数组。
  2. $defaults: 定义了 $args 参数的默认值。 如果用户没有传递 $args 参数,或者 $args 参数中缺少某些键,就会使用这些默认值。
  3. wp_parse_args( $args, $defaults ): 将用户传递的 $args 参数和默认值合并。 这样,即使用户只传递了部分参数,也能保证所有参数都有值。
  4. wp_revisions_enabled( $post ): 检查文章是否启用了修订功能。 如果文章没有启用修订功能,并且 $args['check_enabled']true (默认值),就直接返回一个空数组。
  5. $query_args: 构建一个用于查询修订版本的参数数组。 这个数组包含了 post_type (设置为 'revision')、post_parent (设置为文章的 ID)、posts_per_pagefieldsorderbyorder 等参数。
  6. suppress_filters: 设置为false,允许对查询结果进行过滤,提供更大的定制化空间。
  7. apply_filters( 'wp_get_post_revisions_args', $query_args, $post ): 这是一个钩子 (filter hook),允许开发者修改用于查询修订版本的参数数组。 你可以使用这个钩子来进一步定制查询行为。
  8. get_posts( $query_args ): 使用 get_posts() 函数来查询修订版本。 get_posts() 是 WordPress 中一个非常强大的函数,可以用于查询各种类型的文章。
  9. apply_filters( 'wp_get_post_revisions', $revisions, $post ): 这是另一个钩子 (filter hook),允许开发者修改查询到的修订版本数组。 你可以使用这个钩子来对修订版本进行过滤、排序或其他处理。
  10. return apply_filters( 'wp_get_post_revisions', $revisions, $post ): 返回查询到的修订版本数组。

总结一下,wp_get_post_revisions() 函数的内部机制可以概括为以下几步:

  1. 获取文章对象。
  2. 合并用户参数和默认参数。
  3. 检查文章是否启用了修订功能。
  4. 构建查询参数数组。
  5. 使用 get_posts() 函数查询修订版本。
  6. 应用过滤器钩子。
  7. 返回修订版本数组。

六、使用场景:让时光倒流

wp_get_post_revisions() 函数有很多实用的使用场景,例如:

  • 版本控制界面: 创建一个用户友好的界面,让用户可以查看和恢复文章的修订版本。
  • 自动备份: 定期获取文章的修订版本,并将其保存到数据库或其他存储介质中,以防止数据丢失。
  • 差异比较: 比较文章的不同修订版本,找出修改的内容。
  • 撤销操作: 实现一个“撤销”按钮,让用户可以轻松地恢复到之前的版本。

七、注意事项:小细节,大影响

在使用 wp_get_post_revisions() 函数时,需要注意以下几点:

  • 性能: 获取大量的修订版本可能会影响性能。 建议限制返回的修订版本数量,或者使用缓存技术来提高性能。
  • 权限: 只有具有足够权限的用户才能查看文章的修订版本。
  • 安全: 在显示修订版本的内容时,要进行适当的过滤和转义,以防止 XSS 攻击。 特别是,要使用 esc_html() 函数来转义 HTML 标签。

八、实例:创建一个简单的版本控制界面

下面是一个简单的例子,演示如何创建一个版本控制界面,让用户可以查看和恢复文章的修订版本。

<?php
/**
 * 显示文章的修订版本列表。
 *
 * @param int $post_id 文章 ID。
 */
function display_post_revisions( $post_id ) {
    $revisions = wp_get_post_revisions( $post_id );

    if ( ! empty( $revisions ) ) {
        echo '<h2>修订版本</h2>';
        echo '<ul>';
        foreach ( $revisions as $revision ) {
            $revision_date = date( 'Y-m-d H:i:s', strtotime( $revision->post_modified ) );
            $diff_url = add_query_arg(
                array(
                    'action'   => 'diff',
                    'left'     => $revision->ID,
                    'right'    => $post_id,
                    'revision' => $revision->ID,
                ),
                admin_url( 'revision.php' )
            );

            echo '<li>';
            echo '<a href="' . esc_url( $diff_url ) . '">修订版本: ' . esc_html( $revision_date ) . '</a>';
            echo '</li>';
        }
        echo '</ul>';
    } else {
        echo '<p>这篇文章还没有任何修订版本。</p>';
    }
}

// 在文章编辑页面添加一个 Metabox 来显示修订版本列表。
function add_revision_metabox() {
    add_meta_box(
        'revision_metabox',
        '修订版本',
        'display_post_revisions_metabox',
        'post',
        'normal',
        'default'
    );
}
add_action( 'add_meta_boxes', 'add_revision_metabox' );

function display_post_revisions_metabox( $post ) {
    display_post_revisions( $post->ID );
}
?>

这段代码做了以下几件事:

  1. 定义了一个 display_post_revisions() 函数,用于显示文章的修订版本列表。
  2. 使用 wp_get_post_revisions() 函数获取文章的修订版本。
  3. 遍历修订版本数组,并输出每个修订版本的链接。链接指向 WordPress 自带的修订版本比较页面。
  4. 定义了一个 add_revision_metabox() 函数,用于在文章编辑页面添加一个 Metabox。
  5. 使用 add_meta_box() 函数添加 Metabox。
  6. 定义了一个 display_post_revisions_metabox() 函数,用于在 Metabox 中显示修订版本列表。

将这段代码添加到你的主题的 functions.php 文件中,或者创建一个自定义插件。然后在文章编辑页面,你就可以看到一个包含修订版本列表的 Metabox。

九、总结:时光旅行,触手可及

wp_get_post_revisions() 函数是 WordPress 中一个非常实用的函数,可以让你轻松地获取文章的修订版本。 通过深入了解它的内部机制和使用场景,你可以更好地利用它来管理你的文章内容,实现版本控制、自动备份和差异比较等功能。 掌握它,就像拥有了一台时光机,可以随时回到过去,找回你的灵感和创意。

希望今天的讲座对你有所帮助!下次再见!

发表回复

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