Display revision if post status is pending

I’m trying to display the latest post revision if the page is “pending”, by default the page displays a 404 if it is pending. But I want it to show the latest revision until the page is updated.

The code below doesn’t seem to display anything but the title, I have used a hook to the wp_insert_post_data function which changes the status of the post to “pending” if the users role isn’t admin.

Read More

The post is set to pending in the database, but I cannot get the below code to show the latest revision?

I also don’t know how to prevent it from redirecting to a 404 page? If I am logged in it will show the post otherwise a 404 page.

    <?php while (have_posts()) : the_post(); ?>    
            <h1><?php the_title(); ?></h1>                          
        <?php 
        echo get_post_status(); //echo's pending
        if(get_post_status() == 'pending') {
            $query = new WP_Query(array('post_type' => 'revision', 'post_parent' => '7', 'posts_per_page' => 1)); // 7 is the current page ID
            if ($query->have_posts()) {                 
                while ($query->have_posts()) {                      
                    $query->the_post();                     
                    the_content();
                    echo $post->ID;
                }
            }
            wp_reset_postdata();
        } else {
            the_content(); 
        }               
        ?>           
    <?php endwhile; ?>
<?php endif; ?>

Any advice? Is there an easier way to show the revision if the page is pending?

Thanks !

Edit:

Okay I seem to have it working using the code below:

if(get_post_status() == 'pending') {
   $query = 'SELECT ID FROM `wp_posts` WHERE `post_parent` = '.$post->ID.' AND `post_type` = "revision" AND `post_status` = "pending" AND `post_title` <> "Auto Draft" AND TRIM(`post_content`) <> "" AND `post_name` NOT LIKE "%autosave%" ORDER BY `post_modified` DESC LIMIT 1';
   $revision_id = $wpdb->get_var($query);
   $revision = wp_get_post_revision($revision_id);
   $content = $revision->post_content;              
   $content = apply_filters('the_content', $content);
   $content = str_replace(']]>', ']]>', $content);
   echo $content;
   wp_reset_postdata();
} else {
   the_content(); 
}

So now the question is – How can I prevent a page which is set as pending to redirecting to the 404 page?

Related posts

Leave a Reply

2 comments

  1. It took me a while but I got it! This works as follows:

    1. Since you have no reference to the post other than the URI, we segment out the URI to check for a page with that page_name
    2. If there is a page, we get the latest revision child
    3. Hack the query to force our revision slug to source the page

    This works swell because it gives the appearance of a working permalink. It acts as a pseudo permalink.

    add_action( 'wp', 'override_404' );
    function override_404($query) {
    
        if(is_404):
    
            $uri = trim($_SERVER['REQUEST_URI'], '/');
            $segments = explode('/', $uri);
            $slug_index = count($segments);
    
            $page_slug = $segments[$slug_index - 1];
            $page = get_page_by_path($page_slug, OBJECT, 'page');
    
            $revision_args = array('post_parent' => $page->ID, 'post_type' => 'revision', 'post_status' => 'inherit', 'numberposts' => 1);
            $revision = array_shift(get_children($revision_args));
    
            if($revision):
                $query->query_vars['pagename'] = $revision->page_name;          
                $query->query_string = "pagename={$revision->page_name}";
                $query->request = $revision->page_name;
                $query->matched_rule = "({$revision->page_name})(/[0-9]+)?/?$";
                $query->matched_query = "pagename={$revision->page_name}&page=";
                $query->did_permalink = 1;
            endif;
    
        endif;
    
        return $query;
    }
    

    The only caveat is sometimes the slug does not save until you publish the page. In order for this to work correctly, the slug must be in the database. Cheers!

  2. I’ve been working on this issue recently, and I would like to post my solution, if the 404 override doesn’t work.

    Basically WordPress set pending post status to private instead of public (that is why you’re not able to see it, if you’re not logged in as admin), so we need to reset it:

    function override_pending_post_status() {
      register_post_status( 'pending', array(
        'label'       => _x( 'Pending', 'post' ),
        'protected'   => true,
        '_builtin'    => true, /* internal use only. */
        'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ),
        'public'      => true,
      ) );
    }
    
    add_action( 'init', 'override_pending_post_status' );