在 Wordpress 中使预定帖子可用的代码中断预览 问题代码重现步骤一些观察:

问题描述

问题

有一段代码可以通过 URL 为外部用户提供预定的帖子。代码本身工作得很好 - 但是它似乎与编辑器的预览功能混乱。 导致此问题的原因是什么?如何解决

代码

下面的代码是我用来使 schedulesd 帖子可用的代码

//this is inside the functions.PHP
function show_future_posts($posts)
{
    global $wp_query,$wpdb;

    if (is_single() && $wp_query->post_count == 0) {
        $posts = $wpdb->get_results($wp_query->request);
        for ($i = 0; $i < sizeof($posts); $i++) {
            if ($posts[$i]->post_status == 'trash') {
                unset($posts[$i]);
                $posts = array_values($posts);
            }
        }
    }
    return $posts;
}

add_filter('the_posts','show_future_posts');

重现步骤

  1. 创建新帖子
  2. 安排发布时间
  3. 编辑内容
  4. 点击预览

一些观察:

  • 只要帖子被标记为草稿,预览就可以正常工作。
  • 更新/保存 (ctrl + s) 后预览正确
  • 我认为这与 this 等已知问题无关。删除有问题的代码时,自动保存功能工作正常
  • 发布的帖子与预定的帖子表现出相同的行为
  • 编辑器(古腾堡/​​认)在这种情况下似乎无关紧要

非常感谢任何帮助。谢谢!

解决方法

我找到了解决办法:
问题是 $posts 在条件内被新的帖子数组覆盖。新的帖子数组不包含用于预览的最近更改。所以我做了一个检查,帖子是否处于 prview 模式,然后在新的帖子数组中覆盖帖子内容。
下面的代码是我想出来的。它尚未优化,但有效。请随时在评论中分享您的优化。我会确保将它们包含在此解决方案中。

function show_future_posts($posts)
{
    global $wp_query,$wpdb;

    if (is_single() && $wp_query->post_count == 0) {

        $initial_posts = $posts; //save initial posts,in case we need to overwrite the new $posts content
        $posts = $wpdb->get_results($wp_query->request);
        /*
         * $initial_posts_exists_and_has_content is true when previewing scheduled posts.
         * We then can overwrite the post-content with the initial content
         * When viewing already published posts it is also true,but doesn`t contain the latest changes.
         * The content will still be overwritten,but this wont have any effect,since $initial_posts and $posts are
         * equal in this case.
         */
        $initial_posts_exists_and_has_content = !empty($initial_posts) && !is_null($initial_posts[0]->post_content);
        if($initial_posts_exists_and_has_content){
            $posts[0]->post_content = $initial_posts[0]->post_content;
        }

        for ($i = 0; $i < sizeof($posts); $i++) {
            if ($posts[$i]->post_status == 'trash') {
                unset($posts[$i]);
                $posts = array_values($posts);
            }
        }
    }
    return $posts;
}